Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frequency incorrect when using new style DAC dac_cosine libraries, also glitches on channel 1 #10192

Open
1 task done
Jay-esp opened this issue Aug 18, 2024 · 3 comments
Open
1 task done
Labels
Status: Awaiting triage Issue is waiting for triage

Comments

@Jay-esp
Copy link

Jay-esp commented Aug 18, 2024

Board

ESP32-WROOM-32

Device Description

devkit

Hardware Configuration

DAC output 1 (or 2) pins 25 or 26, tektronix oscilloscope for measurements

Version

v3.0.3

IDE Name

arduino 1.18.19

Operating System

windows 10

Flash frequency

80

PSRAM enabled

no

Upload speed

921600

Description

I generate a sine wave on one of the dac outputs, the old method with dac.h driver generates for a 500Hz setting a 520Hz signal, the new method with dac_cosine libraries generates 390Hz for the 500Hz setting, comparable errors on other frequencies.
Plus there are spikes in the signal when using dac 1, not with dac2, actually on both old and new method, this is documented on the net and not resolved, the spikes are around the signal changes so at 90,180,270,360 degrees

Sketch

New code that generates 390Hz instead of 500

#include <driver/dac_cosine.h>
dac_cosine_handle_t dac_chan_handle;
void setup() {
  outputCW(500);
}

void loop() {
  delay(1000);
}

void outputCW( uint32_t freq ) {
  dac_cosine_config_t dac_cos_cfg = {
    .chan_id = DAC_CHAN_1, // GPIO25 pin on ESP32
    .freq_hz = freq,       // DAC frequency in Hz
    .clk_src = DAC_COSINE_CLK_SRC_DEFAULT, // RC_FAST
    .atten = DAC_COSINE_ATTEN_DEFAULT, // normal amplitude
    .phase = DAC_COSINE_PHASE_0, // phase value (0 or 180)
    .offset = 0,           // offset value -128 ~ +127
    .flags = { .force_set_freq = true }
  };

  if ( dac_chan_handle != NULL ) {
    dac_cosine_stop( dac_chan_handle );
    dac_cosine_del_channel( dac_chan_handle );
  }
  // Configure the DAC-CW channel
  dac_cosine_new_channel( &dac_cos_cfg, &dac_chan_handle );
  // Start te DAC-CW Generator on DAC channel
  dac_cosine_start( dac_chan_handle );
}


Old code that generates 520Hz

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

void setup() {
  DAC_Start();
  DAC_SetScale(0);
  DAC_SetFrequency(500);
}

void loop() {
  delay(2000);
}

void DAC_Start(void) {
  // Enable tone generator common to both channels
  SET_PERI_REG_MASK(SENS_SAR_DAC_CTRL1_REG, SENS_SW_TONE_EN);
  // Enable / connect tone tone generator on / to this channel
  SET_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN1_M);
  // Invert MSB, otherwise part of waveform will have inverted
  SET_PERI_REG_BITS(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_INV1, 2, SENS_DAC_INV1_S);
  // enable channel
  dac_output_enable(DAC_CHANNEL_1);
}

void DAC_SetFrequency(double frequency)
{
  // f = s * 127 / v

  double f, delta, delta_min = 999999999.0;
  uint16_t divi = 0, step = 1, s;
  uint8_t clk_8m_div = 0; // 0 bis 7
  for (uint8_t div = 1; div < 9; div++)
  {
    s = round(frequency * div / 127);
    if ((s > 0) && ((div == 1) || (s < 1024)))
    {
      f = 127 * s / div;
      delta = abs(f - frequency);
      if (delta < delta_min)
      {
        step = s;
        divi = div - 1;
        delta_min = delta;
      }
    }
  }
  frequency = 127 * step / (divi + 1);
  REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, divi);
  SET_PERI_REG_BITS(SENS_SAR_DAC_CTRL1_REG, SENS_SW_FSTEP, step, SENS_SW_FSTEP_S);
}

void DAC_SetScale(int scale) {
  /*
     Scale output of a DAC channel using two bit pattern:
     - 00: no scale
     - 01: scale to 1/2
     - 10: scale to 1/4
     - 11: scale to 1/8
  */
  SET_PERI_REG_BITS(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_SCALE1, scale, SENS_DAC_SCALE1_S);
}

void DAC_Stop(void) {
  CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN1_M);
  dac_output_disable(DAC_CHANNEL_1);
}

Debug Message

no errors are generated

Other Steps to Reproduce

its consistant using small demo code and minimal hardware

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@Jay-esp Jay-esp added the Status: Awaiting triage Issue is waiting for triage label Aug 18, 2024
@lbernstone
Copy link
Contributor

lbernstone commented Aug 18, 2024

You will probably need to ask this at https://github.com/espressif/esp-idf/issues, since this is pure esp-idf code. First thing to check, however, is to collect the results of dac_cosine_new_channel and dac_cosine_start to make sure there are no errors there.

@Jay-esp
Copy link
Author

Jay-esp commented Aug 18, 2024

You will probably need to ask this at https://github.com/espressif/esp-idf/issues, since this is pure esp-idf code. First thing to check, however, is to collect the results of dac_cosine_new_channel and dac_cosine_start to make sure there are no errors there.

I dont use the idf, just the arduino ide, tx for the tip but both functions return no error

@lbernstone
Copy link
Contributor

The code comes from upstream, so it can't be fixed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting triage Issue is waiting for triage
Projects
None yet
Development

No branches or pull requests

2 participants