CS42448 - Teensy Audio lib hookup how-to?

propa

Well-known member
Hi

Just got my CS42448 board back and soldered it all together, just trying to see if it works at all, not sure how to hook it up via the audio design tool.

Usually with SGTL, you don't output the audio through there, there's an I2S object, but this codec uses TDM. If I wanted to just send a sine wave out of one output on the CS codec how would I hook it up?

This is my attempt, in picture attached Screen Shot 2022-02-11 at 17.21.47.png

I did find somewhere that a zero bit may need to be sent, or something to kick start to the process.

Any ideas or kicks in the right direction would be really helpful
 
Seems to work fine over USB, but analog section input and output is not happening.

Checked whether .enable returns a true value and seems fine. Sinewave via USB works fine, so works as a sound card with two channels.

I've tried the "write(CS42448_Functional_Mode, 0xF4 | 0x01 );" fix and nothing happening there.

Measured VQ and seems fine @5v.



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

// GUItool: begin automatically generated code
AudioInputTDM            tdm1;           //xy=107.66667938232422,205.77777099609375
AudioOutputTDM           tdm2;           //xy=480.55558013916016,189.88887786865234
AudioOutputUSB           usb1;           //xy=541.7948760986328,390.2319755554199
AudioConnection          patchCord1(tdm1, 0, tdm2, 0);
AudioConnection          patchCord2(tdm1, 0, usb1, 0);
AudioConnection          patchCord3(tdm1, 1, tdm2, 1);
AudioConnection          patchCord4(tdm1, 1, usb1, 1);
AudioConnection          patchCord5(tdm1, 2, tdm2, 2);
AudioConnection          patchCord6(tdm1, 3, tdm2, 3);
AudioConnection          patchCord7(tdm1, 4, tdm2, 4);
AudioConnection          patchCord8(tdm1, 5, tdm2, 5);
AudioConnection          patchCord9(tdm1, 6, tdm2, 6);
AudioConnection          patchCord10(tdm1, 7, tdm2, 7);
AudioConnection          patchCord11(tdm1, 8, tdm2, 8);
AudioConnection          patchCord12(tdm1, 9, tdm2, 9);
AudioConnection          patchCord13(tdm1, 10, tdm2, 10);
AudioConnection          patchCord14(tdm1, 11, tdm2, 11);
AudioConnection          patchCord15(tdm1, 12, tdm2, 12);
AudioConnection          patchCord16(tdm1, 13, tdm2, 13);
AudioConnection          patchCord17(tdm1, 14, tdm2, 14);
AudioConnection          patchCord18(tdm1, 15, tdm2, 15);
AudioControlCS42448      cs42448_1;      //xy=191.77781677246094,363.1111755371094
// GUItool: end automatically generated code


void setup() {
  // put your setup code here, to run once:
  delay(5.0);
  AudioMemory(50);
  cs42448_1.enable();


  if (cs42448_1.enable() == true)
  {
    Serial.println("is ok");
  }
 // write(CS42448_Functional_Mode, 0xF4 | 0x01 );
  cs42448_1.volume(0.1);
  cs42448_1.inputLevel(0.2);
}

void loop() {
}

here's my schematic:

Screen Shot 2022-02-11 at 19.59.30.png

Not sure what to try next, I know there's a few people that have got the CS42448 working around here, seemed to have exhausted the tips or suggestions on what to test.

Input section:
Screen Shot 2022-02-11 at 20.01.55.png

Output:
Screen Shot 2022-02-11 at 20.02.02.png

Teensy part:
Screen Shot 2022-02-11 at 20.02.10.jpg
 
Quick question if I update the file "control_cs424448.cpp" are changes instantly recognised by Teensyduino IDE?

For instance i just checked to see if anything was happening when I changed the enable function, so I chucked garbage into it:

Code:
bool AudioControlCS42448::enable(void)
{
	Wire.begin();
	// TODO: wait for reset signal high??
	if (!wrsfgite(CS42448_Power_Control, 0xFF)) return false; // power down
	if (!wrisfgte(CS42448_Functional_Mode, default_config, sizeof(default_config))) return false;
	if (!wrsfgsfgite(CS42448_Power_Control, 0)) return false; // power up
    __kjbhgidfgoijodijfgwrite(CS42448_Functional_Mode, 0xF4 | 0x01 );
	return true;
}

Expecting Arduino/Teensydui's compiler to through some errors at me, nothing changed, so I'm convinced no change is being seen.

Maybe I'm editing the wrong file, the file I'm editing is from Home>Documents>Arduino>Libraries>Audio-Lib>control_cs424448.cpp

Maybe I haven't exhausted all options, this may not work just changing this bit. I just need to make sure.
 
Just to note, I'm using a Teensy 4.0, ran wire scanner and detects a device:

"device found at address 0x48 (ADS1115,PN532,TMP102,LM75,PCF8591)"

found where the audio library lives by using verbose mode in settings:
/Applications/Teensyduino.app/Contents/Java/hardware/teensy/avr/libraries/...

But no luck on changing the magic bit sadly! Maybe I have a bad soldering job
 
have you tried with more audio memory? and maybe volume() and inputLevel() at 1.0?
I would also try without the USB audio output (just in case is making some conflict)
 
have you tried with more audio memory? and maybe volume() and inputLevel() at 1.0?
I would also try without the USB audio output (just in case is making some conflict)

I have just tried now, and still not getting anything

Code:
// Advanced Microcontroller-based Audio Workshop
//
// http://www.pjrc.com/store/audio_tutorial_kit.html
// https://hackaday.io/project/8292-microcontroller-audio-workshop-had-supercon-2015
// 
// Part 2-8: Oscillators


///////////////////////////////////
// copy the Design Tool code here
///////////////////////////////////
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
//AudioOutputUSB           usb1;
AudioInputTDM            tdm1;           //xy=125.44445419311523,183.55555725097656
AudioSynthWaveformSine   sine1;          //xy=235.5555534362793,59.99999237060547
AudioOutputTDM           tdm2;           //xy=480.55558013916016,189.88887786865234
AudioConnection          patchCord6(sine1, 0, tdm2, 0);
AudioConnection          patchCord7(sine1, 0, tdm2, 2);
AudioControlCS42448      cs42448_1;   

void setup() {
  //Serial.begin(9600);
  AudioMemory(80);
  cs42448_1.enable();
  
  if (cs42448_1.enable() == true)
  {
    Serial.println("is ok");
  }
  cs42448_1.volume(1.0);
  sine1.frequency(200);
  sine1.amplitude(0.9);

}
void loop() {
  // use the knobs to adjust parameters
  float knob1 = (float)analogRead(A2) / 1023.0;
  //Serial.println(knob1);
  sine1.frequency(knob1 * 1500 + 50);
}

I think it might be the board itself, and my assumptions about ground/analog ground might be messing everything up.

Thanks for the reply, I've kinda lost quite a bit of momentum with getting the CS working, think I ruined at least one of the chips learning how to solder QFP's.

This is the schematic and boards in it's current state: https://github.com/braindamp/CS42248

I'm sure it must by the analog/digital ground, I thought I could get away with having one big copper pour for ground as the dig/analog sections of the chip are separated.

I have a few boards happy to send in the post to anyone interested, i'm in UK but don't think it'll be too expensive sticking a board across the pond if someone's interested from over there. I do feel a little defeated by this project, so any help is welcome
 
Why are you calling enable() twice on the cs42448_1 ?


Also this looks suspicious:
Code:
void loop() {
  // use the knobs to adjust parameters
  float knob1 = (float)analogRead(A2) / 1023.0;
  //Serial.println(knob1);
  sine1.frequency(knob1 * 1500 + 50);
}
as it updates sine1.frequecy perhaps 100000's of times a second.

I'd suggest:
Code:
void loop() {
  static unsigned long check_knob_time = 0 ;
  if (millis() - check_knob_time >= 50)  // limit changes to every 50ms
  {
    check_knob_time += 50 ;
    // use the knobs to adjust parameters
    float knob1 = (float)analogRead(A2) / 1023.0;
    //Serial.println(knob1);
    sine1.frequency(knob1 * 1500 + 50);
  }
}
 
Why are you calling enable() twice on the cs42448_1 ?


Also this looks suspicious:
Code:
void loop() {
  // use the knobs to adjust parameters
  float knob1 = (float)analogRead(A2) / 1023.0;
  //Serial.println(knob1);
  sine1.frequency(knob1 * 1500 + 50);
}
as it updates sine1.frequecy perhaps 100000's of times a second.

I'd suggest:
Code:
void loop() {
  static unsigned long check_knob_time = 0 ;
  if (millis() - check_knob_time >= 50)  // limit changes to every 50ms
  {
    check_knob_time += 50 ;
    // use the knobs to adjust parameters
    float knob1 = (float)analogRead(A2) / 1023.0;
    //Serial.println(knob1);
    sine1.frequency(knob1 * 1500 + 50);
  }
}

ok so I've changed to:

Code:
// Advanced Microcontroller-based Audio Workshop
//
// http://www.pjrc.com/store/audio_tutorial_kit.html
// https://hackaday.io/project/8292-microcontroller-audio-workshop-had-supercon-2015
// 
// Part 2-8: Oscillators


///////////////////////////////////
// copy the Design Tool code here
///////////////////////////////////
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputTDM            tdm1;           //xy=125.44445419311523,183.55555725097656
AudioSynthWaveformSine   sine1;          //xy=235.5555534362793,59.99999237060547
AudioOutputTDM           tdm2;           //xy=480.55558013916016,189.88887786865234
AudioConnection          patchCord6(sine1, 0, tdm2, 0);
AudioConnection          patchCord7(sine1, 0, tdm2, 2);
AudioControlCS42448      cs42448_1;   

void setup() {
  //Serial.begin(9600);
  AudioMemory(80);
  
  if (cs42448_1.enable() == true)
  {
    Serial.println("is ok");
  }
  cs42448_1.volume(1.0);
  sine1.frequency(200);
  sine1.amplitude(0.9);

}
void loop() {
  static unsigned long check_knob_time = 0 ;
  if (millis() - check_knob_time >= 50)  // limit changes to every 50ms
  {
    check_knob_time += 50 ;
    // use the knobs to adjust parameters
    float knob1 = (float)analogRead(A2) / 1023.0;
    //Serial.println(knob1);
    sine1.frequency(knob1 * 1500 + 50);
}
}

I get an "is ok" in the serial monitor, but no audio. I've must have done something wrong in building the boards schematics/layout or killed the chip.
 
I guess double check every connection and all the register configuration options - I note the datasheet shows 2k pullup resistors
on the I2C lines which your schematic lacks, that might be important as 10k would be expected normally.
 
there is one more thing you could test,
the voltage in the VQ pin has to be about 2.5v, if not, the codec will give no sound.
You can check the voltage on the capacitors connected to that pin which is easier than placing the prove in the pin itself,
or you can try the fix directly by adding a line of code on control_cs42448.cpp

hope it helps
 
I guess double check every connection and all the register configuration options - I note the datasheet shows 2k pullup resistors
on the I2C lines which your schematic lacks, that might be important as 10k would be expected normally.

ok excellent, thank you so much for the advice. I've got the 2k pull ups on the board with the codec on Screen Shot 2022-03-15 at 14.11.14.png

Maybe I have them on the wrong board, are they better placed near the teensy?

I'll go through all the connections with a fine tooth comb, the one main thing I did different was use four layers, and have the middle layers as 5v and 3v3. and the bottom layer full ground, and traces on the top.

And I ignored the part about using a separate analog ground/digital ground. If they're at diff voltage potentials, I may have a big problem, but I thought Gnd for digi and analog were both 0v so there wouldn't be a problem
 
there is one more thing you could test,
the voltage in the VQ pin has to be about 2.5v, if not, the codec will give no sound.
You can check the voltage on the capacitors connected to that pin which is easier than placing the prove in the pin itself,
or you can try the fix directly by adding a line of code on control_cs42448.cpp

hope it helps

voltage is giving 2.5, but I did install the chip badly at one stage and was getting 5v I think. That might have destroyed the chip.

"or you can try the fix directly by adding a line of code on control_cs42448.cpp"

adding a line of code? I think I have changed the Control file to the suggested changes:

Code:
bool AudioControlCS42448::enable(void)
{
	Wire.begin();
	// TODO: wait for reset signal high??
	if (!write(CS42448_Power_Control, 0xFF)) return false; // power down
	if (!write(CS42448_Functional_Mode, default_config, sizeof(default_config))) return false;
	if (!write(CS42448_Power_Control, 0)) return false; // power up
        write(CS42448_Functional_Mode, 0xF4 | 0x01 );
	return true;
}

Is there anything else in that file I should have a look at?

And thank you both so much, a fresh pair of eyes on this is really appreciated
 
Back
Top