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);
}
}