ESP32-S3 I2S STEREO doesn't work

natee.th
Posts: 26
Joined: Fri Feb 10, 2023 5:25 pm

ESP32-S3 I2S STEREO doesn't work

Postby natee.th » Fri Feb 10, 2023 5:41 pm

I am trying to generate a sine wave by external i2s connected to a PCM5102A and outputting only the left channel. Check the signal on the logic analyzer that shows the information in the left channel only. Someone help me please!

Image
I'm modify code from i2s_std.

Code: Select all

/*
 * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Unlicense OR CC0-1.0
 */

#include <stdint.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s_std.h"
#include "driver/gpio.h"
#include "esp_check.h"
#include "sdkconfig.h"

/* Set 1 to allocate rx & tx channels in duplex mode on a same I2S controller, they will share the BCLK and WS signal
 * Set 0 to allocate rx & tx channels in simplex mode, these two channels will be totally separated,
 * Specifically, due to the hardware limitation, the simplex rx & tx channels can't be registered on the same controllers on ESP32 and ESP32-S2,
 * and ESP32-S2 has only one I2S controller, so it can't allocate two simplex channels */
#define EXAMPLE_I2S_DUPLEX_MODE CONFIG_USE_DUPLEX

#define EXAMPLE_STD_BCLK_IO1 GPIO_NUM_2 // I2S bit clock io number
#define EXAMPLE_STD_WS_IO1 GPIO_NUM_3   // I2S word select io number
#define EXAMPLE_STD_DOUT_IO1 GPIO_NUM_4 // I2S data out io number
#define EXAMPLE_STD_DIN_IO1 GPIO_NUM_5  // I2S data in io number
#if !EXAMPLE_I2S_DUPLEX_MODE
#define EXAMPLE_STD_BCLK_IO2 GPIO_NUM_6 // I2S bit clock io number
#define EXAMPLE_STD_WS_IO2 GPIO_NUM_7   // I2S word select io number
#define EXAMPLE_STD_DOUT_IO2 GPIO_NUM_8 // I2S data out io number
#define EXAMPLE_STD_DIN_IO2 GPIO_NUM_9  // I2S data in io number
#endif

#define EXAMPLE_BUFF_SIZE 32

// i2s number
#define EXAMPLE_I2S_NUM (0)
// i2s sample rate
#define EXAMPLE_I2S_SAMPLE_RATE (32000)
// i2s data bits
#define EXAMPLE_I2S_SAMPLE_BITS (16)
// enable display buffer for debug
#define EXAMPLE_I2S_BUF_DEBUG (0)
// I2S read buffer length
#define EXAMPLE_I2S_READ_LEN (16 * 32)

static i2s_chan_handle_t tx_chan; // I2S tx channel handler

int wav_buffer[64] ;

const int audio_table[] = {
32500,33301,34101,34900,35698,36494,37287,38078,38865,39648,40427,41201,41970,42733,43490,44240,
44983,45719,46446,47165,47876,48576,49267,49948,50618,51278,51925,52562,53185,53797,54395,54980,
55552,56109,56652,57181,57694,58192,58675,59142,59592,60026,60443,60844,61227,61593,61941,62271,
62583,62877,63153,63409,63647,63867,64067,64248,64409,64552,64674,64778,64861,64925,64970,64994,
64999,64985,64950,64896,64822,64728,64615,64483,64331,64160,63969,63759,63531,63283,63017,62732,
62429,62108,61769,61412,61038,60646,60237,59811,59369,58910,58436,57945,57439,56918,56382,55832,
55268,54689,54098,53493,52875,52245,51603,50949,50285,49609,48923,48227,47522,46807,46084,45352,
44613,43866,43113,42352,41586,40815,40038,39257,38472,37683,36891,36096,35299,34501,33701,32900,
32100,31299,30499,29701,28904,28109,27317,26528,25743,24962,24185,23414,22648,21887,21134,20387,
19648,18916,18193,17478,16773,16077,15391,14715,14051,13397,12755,12125,11507,10902,10311,9732,
9168,8618,8082,7561,7055,6564,6090,5631,5189,4763,4354,3962,3588,3231,2892,2571,
2268,1983,1717,1469,1241,1031,840,669,517,385,272,178,104,50,15,1,
6,30,75,139,222,326,448,591,752,933,1133,1353,1591,1847,2123,2417,
2729,3059,3407,3773,4156,4557,4974,5408,5858,6325,6808,7306,7819,8348,8891,9448,
10020,10605,11203,11815,12438,13075,13722,14382,15052,15733,16424,17124,17835,18554,19281,20017,
20760,21510,22267,23030,23799,24573,25352,26135,26922,27713,28506,29302,30100,30899,31699,32500
};




/**
 * @brief Scale data to 16bit/32bit for I2S DMA output.
 *        DAC can only output 8bit data value.
 *        I2S DMA will still send 16 bit or 32bit data, the highest 8bit contains DAC data.
 */
int example_i2s_dac_data_scale( int *d_buff,  int *s_buff, uint32_t len)
{
    uint32_t j = 0;
    for (int i = 0; i < len; i++)
    {
        d_buff[j++] = ((s_buff[i])-32500);
        d_buff[j++] = ((s_buff[i])-32500);
        
        
    }
    return (len );

}


static void i2s_example_write_task(void *args)
{

  

    size_t bytes_written;
    int tot_size = sizeof(audio_table);
    int*  i2s_write_buff = (int*)calloc(2048, sizeof( int ));
     int i2s_wr_len = example_i2s_dac_data_scale(i2s_write_buff, ( int *)(audio_table ), tot_size);

    while (1)
    {
         i2s_channel_write(tx_chan, i2s_write_buff, 2048, &bytes_written, 1000);

    }
    // vTaskDelay(1 / portTICK_PERIOD_MS);
    free(i2s_write_buff);
    vTaskDelete(NULL);
}

static void i2s_example_init_std_simplex(void)
{
    /* Setp 1: Determine the I2S channel configuration and allocate two channels one by one
     * The default configuration can be generated by the helper macro,
     * it only requires the I2S controller id and I2S role
     * The tx and rx channels here are registered on different I2S controller,
     * only ESP32-C3, ESP32-S3 and ESP32-H2 allow to register two separate tx & rx channels on a same controller */
    i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
    ESP_ERROR_CHECK(i2s_new_channel(&tx_chan_cfg, &tx_chan, NULL));
    // i2s_chan_config_t rx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
    // ESP_ERROR_CHECK(i2s_new_channel(&rx_chan_cfg, NULL, &rx_chan));

    /* Step 2: Setting the configurations of standard mode and initialize each channels one by one
     * The slot configuration and clock configuration can be generated by the macros
     * These two helper macros is defined in 'i2s_std.h' which can only be used in STD mode.
     * They can help to specify the slot and clock configurations for initialization or re-configuring */
    i2s_std_config_t tx_std_cfg = {
        .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(EXAMPLE_I2S_SAMPLE_RATE),
        .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
        .gpio_cfg = {
            .mclk = I2S_GPIO_UNUSED, // some codecs may require mclk signal, this example doesn't need it
            .bclk = EXAMPLE_STD_BCLK_IO1,
            .ws = EXAMPLE_STD_WS_IO1,
            .dout = EXAMPLE_STD_DOUT_IO1,
            .din = EXAMPLE_STD_DIN_IO1,
            .invert_flags = {
                .mclk_inv = false,
                .bclk_inv = false,
                .ws_inv = false,
            },
        },
    };
    ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &tx_std_cfg));
}

void app_main(void)
{

    i2s_example_init_std_simplex();

    /* Step 3: Enable the tx channels before writing */
    ESP_ERROR_CHECK(i2s_channel_enable(tx_chan));

    /* Step 4: Create writing task */


    // printf("tot_size: i2s write %d \n", tot_size);

    xTaskCreate(i2s_example_write_task, "i2s_example_write_task", 4096, NULL, 5, NULL);
}

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32-S3 I2S STEREO doesn't work

Postby ESP_Sprite » Sat Feb 11, 2023 2:32 am

example_i2s_dac_data_scale writes the value as an 32-bit int, with the top 16-bit being 0. I2S will interpret the top 16 bit as the right channel and the bottom as the left channel, hence your right channel is silent.

natee.th
Posts: 26
Joined: Fri Feb 10, 2023 5:25 pm

Re: ESP32-S3 I2S STEREO doesn't work

Postby natee.th » Sat Feb 11, 2023 5:27 am

Oh! Thank a lot Mr. ESP_Sprite. :)

Who is online

Users browsing this forum: No registered users and 118 guests