I2s using fixed_mclk

SinkroniusMaximus
Posts: 1
Joined: Wed Sep 12, 2018 7:47 pm

I2s using fixed_mclk

Postby SinkroniusMaximus » Wed Sep 12, 2018 8:24 pm

What is the correct syntax for using fixed_mclk in I2S communication?

I have the following code:

Code: Select all

#include <stdio.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" #include "nvs_flash.h" #include "driver/i2s.h" #include <math.h> #include "soc/rtc_io_reg.h" #include "soc/sens_reg.h" #define SAMPLE_RATE (44100) #define I2S_NUM_0 (0) #define I2S_NUM_1 (1) #define WAVE_FREQ_HZ (440) #define SAMPLE_PER_CYCLE (SAMPLE_RATE/WAVE_FREQ_HZ) long RX_sample_val[2]; int returned; unsigned int i; long TX_sample_val[2]; long Temp_audio[2]; int TX_install_ok, TX_set_pin_ok; int RX_install_ok, RX_set_pin_ok; float sin_float, triangle_float, triangle_step = 65536.0 / SAMPLE_PER_CYCLE; i2s_config_t i2s_config_TX = { .mode = static_cast<i2s_mode_t>(I2S_MODE_MASTER | I2S_MODE_TX), // TX only .sample_rate = 44100,//SAMPLE_RATE, .bits_per_sample = I2S_BITS_PER_SAMPLE_24BIT,//I2S_BITS_PER_SAMPLE_16BIT, //16-bit per channel .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //2-channels .communication_format = static_cast<i2s_comm_format_t>(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // high interrupt priority .dma_buf_count = 2, .dma_buf_len = 128, // .use_apll = true// }; i2s_pin_config_t pin_config_TX = { .bck_io_num = 14, .ws_io_num = 12, .data_out_num = 22, .data_in_num = -1 }; i2s_config_t i2s_config_RX = { .mode = static_cast<i2s_mode_t>(I2S_MODE_MASTER | I2S_MODE_RX), // RX only .sample_rate = 44100,//SAMPLE_RATE, .bits_per_sample = I2S_BITS_PER_SAMPLE_24BIT,//I2S_BITS_PER_SAMPLE_16BIT, //16-bit per channel .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //2-channels .communication_format = static_cast<i2s_comm_format_t>(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // high interrupt priority .dma_buf_count =2, .dma_buf_len = 128, // .use_apll = true, // .fixed_mclk = 169344 }; i2s_pin_config_t pin_config_RX = { .bck_io_num =26, .ws_io_num = 25, .data_out_num = -1, .data_in_num = 23 }; void setup() { Serial.begin(115200); nvs_flash_init(); pinMode(13, OUTPUT);//FSYNC //start I2S transmitter TX_install_ok = i2s_driver_install(static_cast<i2s_port_t>I2S_NUM_1, &i2s_config_TX, 0, NULL); TX_set_pin_ok = i2s_set_pin(static_cast<i2s_port_t>I2S_NUM_1, &pin_config_TX); //start I2S receiver RX_install_ok = i2s_driver_install(static_cast<i2s_port_t>I2S_NUM_0, &i2s_config_RX, 0, NULL); RX_set_pin_ok = i2s_set_pin(static_cast<i2s_port_t>I2S_NUM_0, &pin_config_RX); //Set mclk output to pin 0 for I2S RX REG_WRITE(PIN_CTRL, 0b111111110000); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1); Serial.print(" esp ok: "); Serial.print(ESP_OK); Serial.print("TX install ok: "); Serial.print(TX_install_ok); Serial.print(" TX set pin ok: "); Serial.print(TX_set_pin_ok); Serial.print("RX install ok: "); Serial.print(RX_install_ok); Serial.print(" RX set pin ok: "); Serial.print(RX_set_pin_ok); TaskHandle_t Task1, Task2; xTaskCreatePinnedToCore( codeForTask1, "commTask", 1500, NULL, 1, &Task1, 0); delay(500); // needed to start-up task1 xTaskCreatePinnedToCore( codeForTask2, "driveTask", 1000, NULL, 1, &Task2, 1); } void codeForTask1( void * parameter ) { for (;;) { digitalWrite(13, HIGH); returned = i2s_pop_sample(static_cast<i2s_port_t>I2S_NUM_0, (char *)&RX_sample_val[0], portMAX_DELAY); digitalWrite(13, LOW); TX_sample_val[0] = RX_sample_val[0] & 0x00000000; //ignore right channel for now //shift and also reduce some noise and add zero offset Temp_audio[1] = (RX_sample_val[1] / 1024) + 125288; //copy input sound to output TX_sample_val[1] = RX_sample_val[1]; // Test noise example for output test // // triangle_float = -32767; // // for(i = 0; i < SAMPLE_PER_CYCLE; i++) { // sin_float = sin(i * PI / 180.0); // if(sin_float >= 0) // triangle_float += triangle_step; // else // triangle_float -= triangle_step; // sin_float *= 32767; // // TX_sample_val[0] = 0L; // TX_sample_val[0] += (short)triangle_float; // TX_sample_val[0] = TX_sample_val[0] << 16; // TX_sample_val[0] += (short) sin_float; i2s_push_sample(static_cast<i2s_port_t>I2S_NUM_1, (char *)&TX_sample_val[0], portMAX_DELAY); // } } } void codeForTask2( void * parameter ) { for (;;) { //// Debug to serial monitor // Serial.print("right: "); // Serial.print(TX_sample_val[0]); // Serial.print(" left: "); // Serial.println(TX_sample_val[1]); } } // void loop() { delay(1000); }
The hardware is CJMCU-1334 for TX, which is based around a UDA1334 chip. This chip has a PLL built in for the correct mclk.
CJMCU-1802 for RX, which is based upon PCM1802 chip. This chip has no such PLL built in and requires an external mclk signal.

I do get sound throughput, after days and days of searching, however it is extremely noisy.
I believe the mclk supplied by this code is not right and I want to tune it.

when compiling using '.fixed_mclk' the following message appears:

'i2s_config_t' has no non-static data member named 'fixed_mclk'

The following questions arise: what is the correct syntax? what are the boundaries/units?

Return to “ESP32 Arduino”

Who is online

Users browsing this forum: Google [Bot] and 7 guests