Cannot get I2S to internal DAC to work.

michaelk
Posts: 4
Joined: Sat Jan 02, 2016 5:23 pm

Cannot get I2S to internal DAC to work.

Postby michaelk » Mon Feb 14, 2022 4:16 pm

I have not been able to get the I2S system to output through the internal DAC. I'm using the ESP WROOM 32 but see nothing on output 25 or 26.
I'm precalculating the samples of one period of a sinewave with a frequency of 124.1 Hz. I then continuously send this to the I2C system in a task with two buffers of 1/2 a period.

I presume the I2C / internal DAC does work and there is a bug in the code. What step have I left out or got wrong?

Michael

Code: Select all

#include "freertos/FreeRTOS.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "driver/gpio.h"

#include "soc/rtc_cntl_reg.h"
#include "soc/sens_reg.h"
#include "soc/rtc.h"

#include "driver/dac.h"
#include "driver/i2s.h"

#include <math.h>

#define AMP_DAC 255

#define I2S_NUM (i2s_port_t)0
//Buffer for creating the triangle function
#define NOofSAMPLESperSINE	128
uint32_t sineBuffer[ NOofSAMPLESperSINE ];

//Configuration for the I2S bus
i2s_config_t i2s_config = {
  .mode                 = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN), //Mode
  .sample_rate          = 100000, //Sampling rate
  .bits_per_sample      = I2S_BITS_PER_SAMPLE_16BIT, // the DAC uses only top 8 bits of the MSB
  .channel_format       = I2S_CHANNEL_FMT_RIGHT_LEFT, // Channel format ESP32 supports stereo only
  .communication_format = (i2s_comm_format_t)I2S_COMM_FORMAT_STAND_I2S, //Standard format for I2S
  .intr_alloc_flags     = 0, // Standard Interrupt
  .dma_buf_count        = 2,                    //Number of FIFO buffers
  .dma_buf_len          = NOofSAMPLESperSINE/2, //Size of FIFO buffers
  .use_apll             = false
};

void taskFill(void *pvParameter)
{
    size_t bytesWritten;
    size_t bytesPerDMAbuff = NOofSAMPLESperSINE/2 * sizeof(uint32_t);
	for(;;) {
	// probably don't have to break this up...
		i2s_write((i2s_port_t)0, (const char *)sineBuffer, bytesPerDMAbuff, &bytesWritten, 100);
		i2s_write((i2s_port_t)0, (const char *)sineBuffer + bytesPerDMAbuff, bytesPerDMAbuff, &bytesWritten, 100);
	}
    printf("audio ended\n");
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    printf("stop\n");
	i2s_stop(I2S_NUM);
    vTaskDelete(NULL);
}

//Buffer for creating the triangle function
#define NOofSAMPLESperSINE	128
uint32_t sineBuffer[ NOofSAMPLESperSINE ];

void initSineBuffer() {
  uint32_t usample;

  for( int i=0; i < NOofSAMPLESperSINE; i++ ) {
	  // sinewave peak 0xFF00FF00 to negative peak 0x00000000 - zero is 0x80008000
	  usample = ((uint32_t)(sin( 2.0 * M_PI * ((double)i / NOofSAMPLESperSINE) + 1.0) * AMP_DAC/2 + 0.5)) << 8;
	  sineBuffer[ i ] = (usample << 16) | usample;
  }
}

esp_err_t event_handler(void *ctx, system_event_t *event)
{
    return ESP_OK;
}

void app_main(void)
{
    nvs_flash_init();

    tcpip_adapter_init();
    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
    wifi_config_t sta_config = {
        .sta = {
            .ssid = CONFIG_ESP_WIFI_SSID,
            .password = CONFIG_ESP_WIFI_PASSWORD,
            .bssid_set = false
        }
    };
    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) );
    ESP_ERROR_CHECK( esp_wifi_start() );
    ESP_ERROR_CHECK( esp_wifi_connect() );

#define CTCSS_FREQ 124.1
    initSineBuffer();
    //Remove I2S driver
    // i2s_driver_uninstall((i2s_port_t)0);
    //Customize Configuration
    uint32_t rate = (uint32_t)round( CTCSS_FREQ * (double)NOofSAMPLESperSINE );
    //i2s_config.sample_rate = rate;
    i2s_config.dma_buf_len = NOofSAMPLESperSINE;
    //and install with the new configuration
    i2s_config.sample_rate = rate;
    ESP_ERROR_CHECK( i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL) );
    ESP_ERROR_CHECK( i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN) );
    //Setting the sampling rate
    //ESP_ERROR_CHECK( i2s_set_sample_rates(I2S_NUM, rate) );

    xTaskCreate(taskFill, "fillBuffer", 1024*3, NULL, 10, NULL);

    gpio_set_direction(GPIO_NUM_2, GPIO_MODE_OUTPUT);
    int level = 0;
    while (true) {
        gpio_set_level(GPIO_NUM_2, level);
        level = !level;
        vTaskDelay(300 / portTICK_PERIOD_MS);
    }
}

michaelk
Posts: 4
Joined: Sat Jan 02, 2016 5:23 pm

Re: Cannot get I2S to internal DAC to work.

Postby michaelk » Mon Feb 14, 2022 6:20 pm

One typo .. line should read

Code: Select all

  usample = ((uint32_t)((sin( 2.0 * M_PI * ((double)i / NOofSAMPLESperSINE)) + 1.0) * (double)AMP_DAC/2.0 + 0.5)) << 8;
but this is not the problem.

Who is online

Users browsing this forum: No registered users and 93 guests