This code outputs a continuous wave of the desired frequency.
How can it be made to output a single cycle?
Code: Select all
// 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), // Operating mode
.sample_rate = 100000, // Sampling rate
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // the DAC only uses 8 bits of the MSB
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, // Channel format ESP32 only supports stereo
.communication_format = I2S_COMM_FORMAT_I2S_MSB, // Standard Format for I2S
.intr_alloc_flags = 0, // Standard Interrupt
.dma_buf_count = 2, // Number of FIFO buffers
.dma_buf_len = 32, // Size of the FIFO Buffer
.use_apll = false // clock source
};
void startSine()
{
dac_output_enable(DAC_CHANNEL_2);
SET_PERI_REG_MASK(SENS_SAR_DAC_CTRL1_REG, SENS_SW_TONE_EN);
SET_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN2_M);
SET_PERI_REG_BITS(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_INV2, 2, SENS_DAC_INV2_S);
initDone = true;
}
double setSineFrequency(double frequency)
{
double f, delta, delta_min = 999999999.0;
uint16_t divi = 0, step = 1, s;
for (uint8_t div = 1; div < 9; div++)
{
s = round(frequency * div / SINE_FACTOR);
if ((s > 0) && ((div == 1) || (s < 1024)))
{
f = SINE_FACTOR * s / div;
delta = abs(f - frequency);
if (delta < delta_min)
{
step = s;
divi = div - 1;
delta_min = delta;
}
}
}
frequency = SINE_FACTOR * 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);
return frequency;
}
void controlGenerator()
{
if (!initDone)
startSine();
frequency = setSineFrequency(frequency);
}
void setup()
{
Serial.begin(115200);
controlGenerator();
}
void loop()
{
} // loop()