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?

Who is online

Users browsing this forum: No registered users and 73 guests