TDM with AK4619

john-mike

Well-known member
Update - realized I was mixed up about TDM in and out object pins. But still not getting the correct output.

I'm trying to get the AK4619 codec working via TDM with a 4.1 but with no luck so far. Right now I'm trying to determine if it's the hardware as it's hand soldered to a breakout board, the i2c setup, or something else.
I have the device hook up as descried in the TDM object(s!) on the tool.

I'm seeing the correct clocks on 23,21, and 20 and data on 7.

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthWaveform waveform2;  //xy=371.46665954589844,254.46665954589844
AudioSynthWaveform waveform1;  //xy=409.46665954589844,214.46665954589844
AudioOutputTDM tdm2;           //xy=609.4667911529541,345.4666748046875
AudioConnection patchCord1(waveform2, 0, tdm2, 1);
AudioConnection patchCord2(waveform1, 0, tdm2, 0);
AudioConnection patchCord3(waveform2, 0, tdm2, 2);
AudioConnection patchCord4(waveform1, 0, tdm2, 3);
// GUItool: end automatically generated code

unsigned long current_time;
unsigned long prev_time[8];

byte br[40];

void setup() {
  AudioNoInterrupts();
  delay(500);
  AK2619_start();

  AudioMemory(100);
  waveform1.begin(1, 220, WAVEFORM_SINE);
  waveform2.begin(1, 440, WAVEFORM_SINE);
  AudioInterrupts();
}


void loop() {
  current_time = millis();

  if (current_time - prev_time[0] > 500 && 0) {
    prev_time[0] = current_time;
    Serial.print(AudioProcessorUsageMax());
    Serial.print(" ");
    Serial.print(AudioMemoryUsageMax());
    Serial.println();
    AudioProcessorUsageMaxReset();
    AudioMemoryUsageMaxReset();
  }
}

void AK2619_start() {
  Wire.begin();

  Wire.beginTransmission(0x11);

  Wire.write(0);
  Wire.write(B00110111);  //turn all on

  Wire.endTransmission();

  Wire.beginTransmission(0x11);

  Wire.write(1);
  Wire.write(B11111100);  //tdm

  Wire.endTransmission();

  Wire.beginTransmission(0x11);

  Wire.write(2);
  Wire.write(B00011100);  //tdm

  Wire.endTransmission();


  Wire.beginTransmission(0x11);
  Wire.write(0);
  Wire.endTransmission();

  Wire.beginTransmission(0x11);
  Wire.requestFrom(0x11, 4);

  br[0] = Wire.read();
  br[1] = Wire.read();
  br[2] = Wire.read();
  br[3] = Wire.read();

  Wire.endTransmission();
  for (byte j = 0; j < 4; j++) {
    Serial.println(br[j], BIN);
  }

}
 

Attachments

  • DS1Z_QuickPrint4.png
    DS1Z_QuickPrint4.png
    38.1 KB · Views: 21
Last edited:
More AudioMemory()? TDM objects need quite a lot, try at least 50…
Oh good point. I did that but no luck.

I did realize that there are separate connections for the TDM in and OUT in the tool.
I've removed the input object and changed the wire from 8 to 7 as that's the one sending the data.
My question about the little 44.1k pulse was answered by Paul's great video in the TDA output object as I was just looking at the input ooops.

Now with pin 7 going to the data in of the AK4619 but it's just making a quiet,15kHz sound.

Back to checking reg settings.
 
Last edited:
You don’t appear to be giving it a reset pulse on the PDN pin before initialising it. That’s proved important with other parts…
 
Another good point! Thanks again.
I've added it with no luck though.
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// GUItool: begin automatically generated code
AudioInputTDM tdm1;            //xy=183.46671676635742,349.4666748046875
AudioSynthWaveform waveform2;  //xy=371.46665954589844,254.46665954589844
AudioSynthWaveform waveform1;  //xy=409.46665954589844,214.46665954589844
AudioOutputTDM tdm2;           //xy=609.4667911529541,345.4666748046875
AudioConnection patchCord1(waveform2, 0, tdm2, 1);
AudioConnection patchCord2(waveform1, 0, tdm2, 0);
AudioConnection patchCord3(waveform2, 0, tdm2, 2);
AudioConnection patchCord4(waveform1, 0, tdm2, 3);
// GUItool: end automatically generated code
unsigned long current_time;
unsigned long prev_time[8];
byte br[40];
#define pdn_pin 32

void setup() {
  AudioNoInterrupts();
  pinMode(32, OUTPUT);
  digitalWrite(pdn_pin, 0);
  delay(100);
  digitalWrite(pdn_pin, 1);
  delay(100);
  AK2619_start();
  
  AudioMemory(100);
  waveform1.begin(1, 220, WAVEFORM_SINE);
  waveform2.begin(1, 440, WAVEFORM_SINE);
  AudioInterrupts();
}

void loop() {
  current_time = millis();
  if (current_time - prev_time[0] > 500 && 1) {
    prev_time[0] = current_time;
    Wire.beginTransmission(0x11);
    byte error = Wire.endTransmission();
    Serial.println(error);
    Serial.print(AudioProcessorUsageMax());
    Serial.print(" ");
    Serial.print(AudioMemoryUsageMax());
    Serial.println();
    AudioProcessorUsageMaxReset();
    AudioMemoryUsageMaxReset();
  }
}
void AK2619_start() {
  Wire.begin();
  Wire.beginTransmission(0x11);
  Wire.write(0);
  Wire.write(B00110111);  //turn all on
  Wire.endTransmission();
  Wire.beginTransmission(0x11);
  Wire.write(1);
  Wire.write(B11110000);  //tdm
  Wire.endTransmission();
  Wire.beginTransmission(0x11);
  Wire.write(2);
  Wire.write(B0001000);  //tdm
  Wire.endTransmission();

  Wire.beginTransmission(0x11);
  Wire.write(0);
  Wire.endTransmission();
  Wire.beginTransmission(0x11);
  Wire.requestFrom(0x11, 4);
  br[0] = Wire.read();
  br[1] = Wire.read();
  br[2] = Wire.read();
  br[3] = Wire.read();
  Wire.endTransmission();
  for (byte j = 0; j < 4; j++) {
    printBits(br[j]);
  }
}

void printBits(byte myByte){
  for(byte mask = 0x80; mask; mask >>= 1){
    if(mask  & myByte){
      Serial.print('1');
    }
    else{
      Serial.print('0');
    }
  }
      Serial.println("B ");
}
 
Rebuilt the circuit on perfboard with the same results. I think the breakout is properly soldered as it stops making noise if any wire is removed.
You can hear slight changes in the noise if you change the output frequency so I'm still thinking its an issue with the i2c setup?

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputTDM tdm1;            //xy=183.46671676635742,349.4666748046875
AudioSynthWaveform waveform2;  //xy=371.46665954589844,254.46665954589844
AudioSynthWaveform waveform1;  //xy=409.46665954589844,214.46665954589844
AudioOutputTDM tdm2;           //xy=609.4667911529541,345.4666748046875
AudioConnection patchCord1(waveform1, 0, tdm2, 1);
AudioConnection patchCord2(waveform1, 0, tdm2, 0);
// GUItool: end automatically generated code

unsigned long current_time;
unsigned long prev_time[8];

byte br[40];

#define pdn_pin 32


void setup() {
  AudioNoInterrupts();
  pinMode(32, OUTPUT);
  digitalWrite(pdn_pin, 0);
  delay(100);
  digitalWrite(pdn_pin, 1);
  delay(100);
  AK2619_start();


  AudioMemory(100);
  waveform1.begin(1, 220, WAVEFORM_SINE);
  waveform2.begin(1, 440, WAVEFORM_SINE);
  AudioInterrupts();
}


void loop() {
  current_time = millis();

  if (current_time - prev_time[0] > 1000 && 1) {
    prev_time[0] = current_time;
    Wire.beginTransmission(0x11);
    byte error = Wire.endTransmission();
    Serial.print(error);
    waveform1.frequency(random(10, 100) * 10.0);
    waveform2.frequency(random(10, 100) * 10.0);

    Serial.print(" ");
    Serial.print(AudioProcessorUsageMax());
    Serial.print(" ");
    Serial.print(AudioMemoryUsageMax());
    Serial.println();
    AudioProcessorUsageMaxReset();
    AudioMemoryUsageMaxReset();
  }
}

void AK2619_start() {
  Wire.begin();

  Wire.beginTransmission(0x11);

  Wire.write(0);
  Wire.write(B00110110);  //turn all on

  Wire.endTransmission();

  Wire.beginTransmission(0x11);

  Wire.write(1);
  Wire.write(B11111100);  //tdm

  Wire.endTransmission();

  Wire.beginTransmission(0x11);

  Wire.write(2);
  Wire.write(B00011100);  //tdm

  Wire.endTransmission();

  // Wire.beginTransmission(0x11);
  // Wire.write(12);
  // Wire.write(B0000000);  //dacxsel sdin 1 vs 2?
  // Wire.endTransmission();

  Wire.beginTransmission(0x11);

  Wire.write(0);
  Wire.write(B00110111);  //turn all on AGAIN

  Wire.endTransmission();


  Wire.beginTransmission(0x11);
  Wire.write(0);
  Wire.endTransmission();
  Wire.beginTransmission(0x11);
  Wire.requestFrom(0x11, 4);

  br[0] = Wire.read();
  br[1] = Wire.read();
  br[2] = Wire.read();
  br[3] = Wire.read();

  Wire.endTransmission();
  for (byte j = 0; j < 4; j++) {
    printBits(br[j]);
  }
}


void printBits(byte myByte) {
  for (byte mask = 0x80; mask; mask >>= 1) {
    if (mask & myByte) {
      Serial.print('1');
    } else {
      Serial.print('0');
    }
  }
  Serial.println("B ");
}
 
I got a new chip and soldered it using a stencil and paste this time but same results.
I believe I've tried pretty much every combination of TDM settings and they all give similar faint noise that changes when the oscillators change.
Any ideas @Paul ?

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputTDM tdm1;            //xy=183.46671676635742,349.4666748046875
AudioSynthWaveform waveform2;  //xy=371.46665954589844,254.46665954589844
AudioSynthWaveform waveform1;  //xy=409.46665954589844,214.46665954589844
AudioOutputTDM tdm2;           //xy=609.4667911529541,345.4666748046875
AudioConnection patchCord1(waveform1, 0, tdm2, 1);
AudioConnection patchCord2(waveform2, 0, tdm2, 0);
AudioConnection patchCord3(waveform1, 0, tdm2, 2);
AudioConnection patchCord4(waveform2, 0, tdm2, 3);
// GUItool: end automatically generated code

unsigned long current_time;
unsigned long prev_time[8];

byte br[40];

#define pdn_pin 32


void setup() {
  AudioNoInterrupts();
  pinMode(32, OUTPUT);
  digitalWrite(pdn_pin, 0);
  delay(100);
  digitalWrite(pdn_pin, 1);
  delay(100);
  AK2619_start();
  delay(100);


  AudioMemory(100);
  waveform1.begin(1, 220, WAVEFORM_SINE);
  waveform2.begin(1, 440, WAVEFORM_SINE);
  AudioInterrupts();
}


void loop() {
  current_time = millis();

  if (current_time - prev_time[0] > 1000 && 1) {
    prev_time[0] = current_time;

    waveform1.frequency(random(10, 100) * 10.0);
    waveform2.frequency(random(10, 100) * 10.0);

    byte error = 0;
    if (1) {
      Wire.beginTransmission(0x11);
      error = Wire.endTransmission();
      if (error > 0) {
        Serial.print("i2c error ");
        Serial.println(error);
      }
    }

    if (0) {
    Serial.print(AudioProcessorUsageMax());
    Serial.print(" ");
    Serial.print(AudioMemoryUsageMax());
    Serial.println();
    AudioProcessorUsageMaxReset();
    AudioMemoryUsageMaxReset();
  }
}
}

void AK2619_start() {
  Wire.begin();

  Wire.beginTransmission(0x11);
  Wire.write(0);
  Wire.write(B00110111);  //turn all on
  Wire.endTransmission();

  delay(10);

  Wire.beginTransmission(0x11);
  Wire.write(1);
  Wire.write(B11111100);  //tdm
  Wire.endTransmission();

  Wire.beginTransmission(0x11);
  Wire.write(2);
  Wire.write(B00011111);  //tdm
  Wire.endTransmission();

  Wire.beginTransmission(0x11);
  Wire.write(3);
  Wire.write(B00000000);  //clock
  Wire.endTransmission();

  if (1) {
    byte rn = 4;
    Wire.beginTransmission(0x11);
    Wire.write(0);
    Wire.endTransmission();
    Wire.beginTransmission(0x11);

    Wire.requestFrom(0x11, rn);
    for (byte j = 0; j < rn; j++) {
      br[j] = Wire.read();
    }
    Wire.endTransmission();
    for (byte j = 0; j < rn; j++) {
      Serial.print(j, HEX);
      Serial.print(" ");
      printBits(br[j]);
    }
    Serial.println();
  }
}

void printBits(byte myByte) {
  for (byte mask = 0x80; mask; mask >>= 1) {
    if (mask & myByte) {
      Serial.print('1');
    } else {
      Serial.print('0');
    }
  }
  Serial.println(" ");
}
 
What analog input mode are you using on the AK4619? The chip has three possible ways to connect your audio. The AK4619 datasheet has this information:

9.7. Analog input mode​

Three analog input modes are available: single-ended input, differential input, and pseudo-differential input. These modes are selected by ADxLSEL[1:0], ADxRSEL[1:0] bits(x = 1, 2), (Table 10).

IN single-ended mode, 2:1 multiplexer is used to select which pin to route to each ADC input.

Pseudo-differential signals may not be applied in differential input mode.

NB: the default is differential mode. Depending on which analog input pins you are using, you may need to select the correct mode by writing to the analog input setting register (register 0x0b). In my case, I am using single-ended mode 1, so my set-up code includes the following:

C:
  // ================== Values to send to the Analog Input mode register

  // Inputs to AIN1L, AIN1R, AIN4L and AIN4R
#define SINGLE_ENDED_MODE_1 0b01010101
  // Inputs to AIN2L, AIN2R, AIN5L and AIN5R
#define SINGLE_ENDED_MODE_2 0b10101010

  // Inputs to AIN3L/GND3L, AIN4L/GND4R. AIN6L/GND6L and AIN6R/GND6R
#define PSEUDO_MODE 0b11111111

  unsigned int AK4619_INPUT_MODE = SINGLE_ENDED_MODE_1;  // Set this variable to the required input mode register setting value


  Wire.beginTransmission(CodecAddress);  // Send START to AK4619 I2C Address = 0x10 (CAD pin = Low) or 0x11 (CAD pin = High)
  Wire.write(AK4619_ADC_ANALOG_INPUT);   // Send to the ADC Analog Input Setting register
  Wire.write(AK4619_INPUT_MODE);         // Send the data to set input mode
  returnCode = Wire.endTransmission();   // Send STOP
 
This is my set-up code for the AK4619 codec.

C:
void configure_AK4619_Codec(int CodecAddress) {

  uint8_t returnCode;

  // Do NOT call this function directly: use the setUpCodec() function above as this will ensure the correct configuration function for the fitted Codec is called

  /* Set audio inputs to Single-Ended1 mode See table 10, p43 in the AK4619 Datasheet
     Single-Ended1 mode uses the following analog inputs on the AK4619 chip

     Pin  Input
     16   AIN1L
     14   AIN1R
     12   AIN4L
     10   AIN4R

  */

  // ================== Values to send to the Analog Input mode register

  // Inputs to AIN1L, AIN1R, AIN4L and AIN4R
#define SINGLE_ENDED_MODE_1 0b01010101
  // Inputs to AIN2L, AIN2R, AIN5L and AIN5R
#define SINGLE_ENDED_MODE_2 0b10101010

  // Inputs to AIN3L/GND3L, AIN4L/GND4R. AIN6L/GND6L and AIN6R/GND6R
#define PSEUDO_MODE 0b11111111

  unsigned int AK4619_INPUT_MODE = SINGLE_ENDED_MODE_1;  // Set this variable to the required input mode register setting value


  Wire.beginTransmission(CodecAddress);  // Send START to AK4619 I2C Address = 0x10 (CAD pin = Low) or 0x11 (CAD pin = High)
  Wire.write(AK4619_ADC_ANALOG_INPUT);   // Send to the ADC Analog Input Setting register
  Wire.write(AK4619_INPUT_MODE);         // Send the data to set input mode
  returnCode = Wire.endTransmission();   // Send STOP

#ifdef DEBUG_CODEC_SETUP
  printf("Value sent to AK4619 Analog Input Setting Register = %.8b (0x%.2x)\n", AK4619_INPUT_MODE, AK4619_INPUT_MODE);
  printf("Wire (I2C) returned: %u <%s>\n", returnCode, WIRE_RETURN_CODE[returnCode]);
#endif

  //#define DO_LOOP_THROUGH_TEST

#ifdef DO_LOOP_THROUGH_TEST
  Wire.beginTransmission(CodecAddress);  // Send START to AK4619 I2C Address = 0x10 (CAD pin = Low) or 0x11 (CAD pin = High)
  Wire.write(AK4619_DAC_INPUT_SELECT);   //
  Wire.write(0b1110);                    // Send the ADC1 SDOUT1 -> DAC1 and ADC2 SDOUT2 -> DAC2 See page 49
  returnCode = Wire.endTransmission();   // Send STOP
#endif


  /*
     Power up the ADCs and DACs in the AK4619 by writing to the Power Management Register -  Datasheet page 60

    D7   D6    D5    D4    D3    D2    D1    D0
    0    0   PMAD2  PMAD1  0    PMDA2 PMDA1 RSTN
  */


  delay(100);  // See the AK4619 Datasheet page 42: "Start-up time on Analog input pin" - it recommends waiting 100ms for input caps to charge to avoid pop noise

  Wire.beginTransmission(CodecAddress);                                                 // Send START to AK4619 I2C Address = 0x10 (CAD pin = Low) or 0x11 (CAD pin = High)
  Wire.write(AK4619_PWR_MNGT);                                                          // Send to the Power Management register
  Wire.write(AK4619_PMAD2 | AK4619_PMAD1 | AK4619_PMDA2 | AK4619_PMDA1 | AK4619_RSTN);  // The data
  returnCode = Wire.endTransmission();                                                  // Send STOP

#ifdef DEBUG_CODEC_SETUP
  printf("Value sent to AK4619 Power Management Register = %.8b (0x%.2x)\n", AK4619_PMAD2 | AK4619_PMAD1 | AK4619_PMDA2 | AK4619_PMDA1 | AK4619_RSTN, AK4619_PMAD2 | AK4619_PMAD1 | AK4619_PMDA2 | AK4619_PMDA1 | AK4619_RSTN);
  printf("Wire (I2C) returned: %u <%s>\n", returnCode, WIRE_RETURN_CODE[returnCode]);
#endif

#ifdef SET_MIC_GAIN
  AK4619_SetMicGain(0);
#endif

  // #define DO_ADC_VOLUME_CHECK

#ifdef DO_ADC_VOLUME_CHECK
  for (int v = 0x30; v < 0xff; v++) {
    AK4619_SetADC1_Volume(v);  // -50dB
    delay(20);
  }
#endif
}

One thing I found when reading back the AK4619 registers to check the configration, I had to do a dummy write before reading the registers, otherwise the wrong registers are returned. There's a note in the datasheet Section 2-2, page 58 that states this:
2-2. Random Address Read

The random read operation allows the master to access any memory location at random. Prior to issuing a slave address with the R/W bit = “1”, the master must execute a “dummy” write operation first in order to identify the control register address. The master issues a start condition request, a slave address (R/W bit = “0”) and then the sub address (control register address) to read. After the register address is acknowledged, the master immediately reissues another start condition request as well as the slave address with the R/W bit = “1”. The AK4619 then generates an acknowledge, 1 byte of data, and increments the internal address counter by 1. If the master does not generate an acknowledge but generates a stop condition instead, the AK4619 ceases transmission.

C:
// This returns the values of the AK4619 control registers
// Useful for debugging CODEC set-up problems

void AK4619_readConfig(int CodecAddress) {
  // reads registers values
  uint8_t n = 0;
  uint8_t c = 0;
  uint8_t returnCode;

  // Do a 'dummy' write to the AK4619 to 'reset' the register location
  // See Page 58: '2-2. Random Address Read' in the AK4619 datasheet
  // The chip automatically increments its internal address counter on each access
  // If we don't do this dummy write we end up reading from the wrong register number(s)

  Wire.beginTransmission(CodecAddress);
  Wire.write(0);
  Wire.requestFrom(CodecAddress, 1);
  returnCode = Wire.endTransmission();

  // Now we can read all the registers correctly!

  uint8_t BytesReturned = Wire.requestFrom(CodecAddress, AK4619_numRegisters);

  printf("Wire.requestFrom(AK4619 registers) returned %u bytes\n", BytesReturned);
 
  while (Wire.available()) {
    c = Wire.read();
    printf("Register 0x%.2x = %.8b (0x%.2x)\n", n, c, c);
    n++;
  }

}
 
Well I tried just setting power on, single ended, and mux loop back and am still getting nothing on the output.
The registers have been reporting back the correct defaults so I'm sure I'm writing and reading to the correct ones.
I've tried a couple different teensys and they both work with sgtl5000s.

Here's how I have it connected:
T4.1 - codec
23 - 8 MCLK
21 - 7 BICK
20 - 6 LRCLK
7 - 1 SDIN1
PDN has a pull down resistor and is set high by the teensy after 100ms.
 
Last edited:
The clock pins are connected correctly, as far as I can tell. What clock frequncies are you seeing on each pin, or at least, are they compatible with the AK4619's requirements?

Your first post contained a screenshot from a scope but I don't see where you stated what that signal was. Which pin were you connected to and what are you expecting to see there?

I'm not very familiar with TDM/I2S pins on the Teensy so I may not have this correct! If you only have the Teensy I2S pin 7 (O1A, which I presume is the same as SDOUT1) connected to the codec SDIN1, shouldn't you actually have the codec SDOUT1 (codec pin 31) going to the Teensy SDIN pin? I'm not sure which pin that is, perhaps IN1 (pin 8)?

In my project, the signal from my audio preamp goes to the AK4619 (in single-ended1 mode). The resulting SDOUT1 goes to SDIN1 on my DSP chip, which does it's magic and sends the processed signal from its SDOUT1 to the AK4619 SDIN1. The AK4619's DAC then sends the analog audio signal to my output stage. The DSP generates the three clock signals for the AK4619 from crystal master oscillator.
 
I just realised that you are using the TDM audio format but the AK4619 defaults to I2S on power-up so you need to configure it to match the TDM data format that the Teensy is using. It will be one of modes 8, 9, 10, or 11, as listed in Table 2, page 32, of the AK4619 datasheet.

My project uses I2S so I never needed to set the audio format in my config routine. I can see you are setting a TDM mode but perhaps it isn't the same as the Teensy is using? Might be worth double-checking that and also the clock setting. Sorry, if that doesn't work, I'm kinda out of ideas!

What sample rate (fs) are you using? With your clock setting of B00000000 the MCLK needs to be 256fs.
 
The teensy is sending the correct clocks. 22.6Mhz to MCLK and 11.3 to BICLK
Teensy pin 7 is transmitting the data to SDIN on the codec. I don't have anything hooked up to the SDOUT of the codec as I'm just trying to get audio out of it first.

The code above has the TDM setup and I've tried it several different ways with the same results.

Thanks for your help, though!
 
The teensy is sending the correct clocks. 22.6Mhz to MCLK and 11.3 to BICLK
Teensy pin 7 is transmitting the data to SDIN on the codec. I don't have anything hooked up to the SDOUT of the codec as I'm just trying to get audio out of it first.

The code above has the TDM setup and I've tried it several different ways with the same results.

Thanks for your help, though!
I could be wrong (I often am!) but if your MCLK is 22.6MHz then since the datasheet states that MCLK = 256fs, dividing 22.6MHz by 256 gives fs = 882.8125kHz!!! When setting the AK4619 clock register to B00000000, as you are doing, then fs must be between 8kHz and 48kHz - see Table 1 in the AK4619 datasheet.

Screenshot 2024-06-01 173902.png
 
Yes I am confused about the whole clock thing hah.
In this table 512fs is listed but there is no way to switch the rest of the TDM to that in table 2.
When I set it to 011 I do get sound but its mangled. The top is channel 1, bottom is 2. 1 isn't clipping as it still has that shape if the amplitudes is much lower. 2 sounds like multiple oscillators getting digitally combines in some funky way.
AD_4nXd1YMF977TchTInfTXwc4GTSUv42Wf534-K_MM17d9pVFGBq6oWjuphvVPT7l-vQdRjpSIEVMdsbMTv__oN4UZRNGMw8erIgr_KWWNesGybQ94apF8vTJfzFKQ3OJkYRI9FjAFCBii_sjUCO1fSQGtfuNXK
.
I glanced at the datasheet for the CS42448 and it seems very similar but the teensy TDM objects works just fine with it.
There aren't any functions to change the Teensy TDM rates so again this might be something only Paul can help with.
I changed the value 256 in this section of output_TDM.cpp to 128 and 512. This halve or doubles the clock rates respectively but with no big change in the output. When I go back to 000 in table 1 I get no audio output no matter the value of "256".
 
Maybe the Teensy audio library cannot set the clock values that the AK4619 requires?

Remembering that I'm using a straightforward two channel (L/R) I2S with the DSP chip generating the clocks, my values are:

MCLK = 8.192MHz
BICLK = 2.048MHz
LRCLK = 32kHz

The sample rate (fs) used by my DSP is 32kHz. In other words, MCLK = 256fs and BICLK = 64fs.

Your channel 1 trace looks vaguely familiar - I may have seen something like that when I was first getting started with the AK4619. It looks like the top and bottom halves of your sine wave have been 'flipped' but don't ask me what the cause is! Perhaps you're getting half a cycle from channel 1, then the other half is from channel 2, because the LRCLK is the wrong frequency?

The fact that you are getting some sort of signal with a different clock register setting in the AK4619 makes me think that the solution is somewhere close! Perhaps @PaulStoffregen can tell you if the Teensy TDM library can support the AK4619 clock frequencies.
 
Back
Top