Page 1 of 1

I2S to internal DAC with APLL make noises.

Posted: Thu Mar 23, 2023 9:52 am
by VladimirG
Hi.
I try to generate sine via I2S and internal DAC but i have some isues with it.
If i use APLL clock for I2S it make me possible to gen my signals but i got glitches.Hi.
I try to generate sine via I2S and internal DAC but i have some isues with it.
If i use APLL clock for I2S it make me possible to gen my signals but i got glitches.
pll_2d_clc is useles, i cannot configure I2S rate to get my sine freq.
My sine is 1kHz and 2kHz and sample rate 16kHz

First i tryed IDF v4, now v5.0.1.
Board is ESP32-wroom-32d
Is it hardware issue?

20000101_221542.png
20000101_221542.png (14.04 KiB) Viewed 1557 times
20000101_213742.png
20000101_213742.png (14.37 KiB) Viewed 1557 times

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #include <assert.h>
  6. #include <freertos/FreeRTOS.h>
  7. #include "freertos/task.h"
  8. #include "freertos/queue.h"
  9. #include "driver/gpio.h"
  10. #include "driver/i2s_std.h"
  11. #include "driver/adc.h"
  12. #include "driver/dac.h"
  13. #include "driver/timer.h"
  14. #include "esp_log.h"
  15. #include "proj_dac.h"
  16. #include "ring_buffer.h"
  17. #include <hal/dac_ll.h>
  18. #include <hal/adc_ll.h>
  19. #include <hal/i2s_ll.h>
  20. #include "esp_intr_alloc.h"
  21.  
  22.  
  23. static const char *TAG = "wave_gen";
  24.  
  25. static QueueHandle_t i2s_queue;
  26.  
  27.  
  28. static const int i2s_num = 0; // i2s port number
  29. #define SND_RATE 16000
  30. #define DAC_SND_RATE 1000
  31.  
  32.  
  33.  
  34. static uint8_t buff[2048];
  35.  
  36. static uint8_t  btest[] = {  
  37. 0, 95,0,95,  0, 93,0,86,  0, 86,0,63,  0, 75,0,41,  0, 63,0,31,
  38. 0, 51,0,41,  0, 41,0,63,  0, 34,0,86,  0, 31,0,95,  0, 34,0,86,
  39. 0, 41,0,63,  0, 51,0,41,  0, 63,0,31,  0, 75,0,41,  0, 86,0,63,
  40. 0, 93,0,86
  41. };// 2 sine (1k & 2k)
  42.  
  43. void
  44. dac_init(void)
  45. {
  46.     static bool inited = false;
  47.     static i2s_chan_handle_t i2s_rx_h;
  48.     static i2s_chan_handle_t i2s_tx_h;
  49.  
  50.         static i2s_chan_config_t i2s_chan_conf = {
  51.                 .auto_clear = false,
  52.                 .id = i2s_num,
  53.                 .role = I2S_ROLE_MASTER,
  54.                 .dma_desc_num = 2,
  55.                 .dma_frame_num = 16
  56.         };
  57.  
  58.         static i2s_std_config_t i2s_conf = {
  59.                 .clk_cfg = {
  60.                         .sample_rate_hz = DAC_SND_RATE,
  61.                     .clk_src = I2S_CLK_SRC_APLL,
  62. //                        .clk_src = I2S_CLK_SRC_DEFAULT,
  63.                         .mclk_multiple = I2S_MCLK_MULTIPLE_512
  64.                 },
  65.                 .slot_cfg = {
  66.                         .data_bit_width = I2S_SLOT_BIT_WIDTH_16BIT,
  67.                         .slot_bit_width = I2S_SLOT_BIT_WIDTH_16BIT,
  68.                         .slot_mode = I2S_SLOT_MODE_STEREO,
  69.                         .slot_mask = I2S_STD_SLOT_BOTH,
  70.                         .bit_shift = false,
  71.                         .ws_pol = true,
  72.                         .ws_width = I2S_SLOT_BIT_WIDTH_16BIT,
  73.                         .msb_right = false
  74.                 },
  75.                 .gpio_cfg = {
  76.                         .bclk = I2S_GPIO_UNUSED,
  77.                         .din = I2S_GPIO_UNUSED,
  78.                         .dout = I2S_GPIO_UNUSED,
  79.                         .mclk = I2S_GPIO_UNUSED,
  80.                         .ws = I2S_GPIO_UNUSED,
  81.                         .invert_flags = {
  82.                                 .bclk_inv = false,
  83.                                 .mclk_inv = false,
  84.                                 .ws_inv = true
  85.                         }
  86.                 }
  87.         };
  88.  
  89.     if(!inited) {
  90.  
  91.  
  92.         ESP_ERROR_CHECK(i2s_new_channel(&i2s_chan_conf, &i2s_tx_h, &i2s_rx_h));
  93.         ESP_ERROR_CHECK(i2s_channel_init_std_mode(i2s_rx_h, &i2s_conf));
  94.         ESP_ERROR_CHECK(i2s_channel_init_std_mode(i2s_tx_h, &i2s_conf));
  95.  
  96.         ESP_LOGI(TAG,"N:%d, B:%d, A:%d, M(rx):%d, M(tx):%d",
  97.                  I2S0.clkm_conf.clkm_div_num,
  98.                  I2S0.clkm_conf.clkm_div_b,
  99.                  I2S0.clkm_conf.clkm_div_a,
  100.                  I2S0.sample_rate_conf.rx_bck_div_num,
  101.                  I2S0.sample_rate_conf.tx_bck_div_num
  102.                  );
  103.  
  104.         I2S0.conf2.lcd_en = 1; //TRM page 318   12.5.3 ADC/DAC mode
  105.         I2S0.conf.rx_short_sync = 0;
  106.         I2S0.conf.tx_short_sync = 0;
  107.         I2S0.conf.rx_msb_shift = 0;
  108.         I2S0.conf.tx_msb_shift = 0;
  109.  
  110.         ESP_ERROR_CHECK(dac_output_enable(DAC_CHANNEL_1));
  111.         ESP_ERROR_CHECK(dac_output_enable(DAC_CHANNEL_2));
  112.  
  113.         ESP_ERROR_CHECK(i2s_channel_enable(i2s_rx_h));
  114.         ESP_ERROR_CHECK(i2s_channel_enable(i2s_tx_h));
  115.         size_t b_writen = 0;
  116.         vTaskDelay(1000 / portTICK_RATE_MS);
  117.  
  118.         i2s_channel_write(i2s_tx_h, btest, sizeof(btest) / sizeof(btest[0]), &b_writen, portMAX_DELAY);
  119.         i2s_channel_write(i2s_tx_h, btest, sizeof(btest) / sizeof(btest[0]), &b_writen, portMAX_DELAY);
  120.         i2s_channel_write(i2s_tx_h, btest, sizeof(btest) / sizeof(btest[0]), &b_writen, portMAX_DELAY);
  121.  
  122.  
  123.         // 1 sample for data buff uint8 [z,R,z,L]
  124.  
  125.  
  126.  
  127.         ESP_ERROR_CHECK(dac_i2s_enable());
  128.         inited = true;
  129.     } else{
  130.         ESP_ERROR_CHECK(i2s_channel_disable(i2s_rx_h));
  131.         ESP_ERROR_CHECK(i2s_channel_disable(i2s_tx_h));
  132.         ESP_ERROR_CHECK(i2s_channel_reconfig_std_clock(i2s_rx_h, &i2s_conf.clk_cfg));
  133.         ESP_ERROR_CHECK(i2s_channel_reconfig_std_clock(i2s_tx_h, &i2s_conf.clk_cfg));
  134.         ESP_ERROR_CHECK(i2s_channel_enable(i2s_rx_h));
  135.         ESP_ERROR_CHECK(i2s_channel_enable(i2s_tx_h));
  136.  
  137.     }
  138.  
  139. }
  140.  
  141. void
  142. dac_single_init(void )
  143. {
  144.     dac_init();
  145.     esp_log_level_set("I2S",ESP_LOG_ERROR);
  146. }

Re: I2S to internal DAC with APLL make noises.

Posted: Fri Mar 24, 2023 11:46 am
by corz.org
Try using the DACs built-in cosine generator.

Re: I2S to internal DAC with APLL make noises.

Posted: Mon Mar 27, 2023 7:37 am
by VladimirG
Finally i need complex signal, not just sine...