TEENSY 4.1 to handle 2 X CS42448 possible?

AntiLoop

Well-known member
Hi everybody,

I would like to wire another CS42448 module so that i can have 12 inputs nd 16 outputs,
but in the teensy audio editor if i have the possibility for 2 TDM outputs with two different set of pins, but it's weird,when i select 2 TDM inputs
on the screen design,the new one shows an "!" and have the same pins suggested as the first TDM input.
I look at the teensy 4.1 specs and i see another I2S port,why on the audio editor those pins are not suggested?

My recapitulation: (I take the names as it come on the screen)

Code:
T4.x PIN                 BCLK1   MCLK1    LRCLK1      RX        TX

tdm1(input1):             21       23      20       8 (IN1)

tdm2(output1):            21      23       20                 7 (OUT1A)



If i look at the specs i have:

T4.x PIN                 BCLK2   MCLK2    LRCLK2      RX            TX

tdm3(input2):              4      33        3        5 (IN2)    

tdm2_1(output2):           4      33        3                      2 (OUT2)

(It strange i must post on the /CODE/ to keep the distances,the preview mode shows more tigthten distances and posting sure does it)

Is the "!" on the second TDM input an impossibility to wire and use this or is there a tricking hack to allow that? :rolleyes:
 
You need something like this:
1722006122205.png

which exports to this:

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

// GUItool: begin automatically generated code
AudioInputTDM            tdm1;           //xy=532,146
AudioInputTDM2           tdm2_1;         //xy=531,423
AudioOutputTDM           tdm2;           //xy=699,152
AudioOutputTDM2          tdm2_2;         //xy=698,423


// GUItool: end automatically generated code
Objects tdm1 and tdm2 are the input and output for SAI1; tdm2_1 and tdm2_2 are on the SAI2 hardware. Note that you need my bugfix for the AudioOutputTDM2 object for tdm2_2 to work correctly. As usual with TDM objects, only wire the even-numbered ports.
 
The Design Tool info pane will tell you which pins to wire for each of the above 4 objects: 7/8/20/21/23 for TDM/SAI1, and 2/5/3/4/33 for TDM2/SAI2
 
Hello,
Now that comes to be more clear,but i 'm not much into pull requests stuffs, i will try that change,
i have no problem with the audio editor,but have errors with your sketch,i only put on it void setup() empty and void loop() empty:

Code:
C:\Users\trans\Documents\Arduino\libraries\Audio\output_tdm2.cpp:112:26: error: qualified-id in declaration before '(' token
  112 | void AudioOutputTDM2::isr(void)
      |                          ^
C:\Users\trans\Documents\Arduino\libraries\Audio\output_tdm2.cpp:151:29: error: qualified-id in declaration before '(' token
  151 | void AudioOutputTDM2::update(void)
      |                             ^
C:\Users\trans\Documents\Arduino\libraries\Audio\output_tdm2.cpp:167:33: error: qualified-id in declaration before '(' token
  167 | void AudioOutputTDM2::config_tdm(void)
      |                                 ^
C:\Users\trans\Documents\Arduino\libraries\Audio\output_tdm2.cpp:225:2: error: expected '}' at end of input
  225 | }
      |  ^
C:\Users\trans\Documents\Arduino\libraries\Audio\output_tdm2.cpp:88:1: note: to match this '{'
   88 | {
      | ^

I think i 've done something wrong,but what?
 
Very hard to tell, I'm not sure what you have or haven't done. I put together this skeleton "sketch" which won't do anything, but it compiles fine for me:
C++:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputTDM            tdm1;           //xy=532,146
AudioInputTDM2           tdm2_1;         //xy=531,423
AudioOutputTDM           tdm2;           //xy=699,152
AudioOutputTDM2          tdm2_2;         //xy=698,423


// GUItool: end automatically generated code

void setup()
{
}

void loop()
{
}

At a guess you've messed up somehow getting a copy of my updated output_tdm2.cpp file. If you go to the bugfix branch in my fork of the Audio library, and download it as a .ZIP file, you should just be able to move that file across. I'd recommend you keep a copy of the original (assuming you haven't already overwritten it...).
1722024441382.png
 
Done it !
I surely have made a bad translation,thank you for the help :p
Is it possible to git clone only a file instead of the whole library zip?
 
No, because that is not a clone of the repo. You can restrict to a branch or tag I think and so forth, but you get all the files for that, since the intention is to be able to submit pull-requests.
 
Thanks MarkT for your advice :)

Now it seems that i have a conflict with the 2 CS42448 together,only one,the first one cs42448_1 makes sound,
i have 2 cs42448 like that in the design:

cs42448 audio board.jpg


The audio editor:

1722098517947.png



cs42448_1 with SCL=19 & SDA=18
cs42448_2 with SCL=24 & SDA=25
They configure ok for the twice

Should i use a different I2S port on the second device,like LCRK_01,BCLK_01,SD_01,SD_IN? And of course I keep MCLK_OUT

My sketch:

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


// GUItool: begin automatically generated code
AudioInputTDM            tdm1;           //xy=146,1894
AudioInputTDM2           tdm2_1;         //xy=148,2202.9998779296875
AudioSynthWaveformSine   sine1;          //xy=343,1789
AudioSynthWaveformSine   sine2;          //xy=346,1843
AudioSynthWaveformSine   sine3;          //xy=350,1895
AudioSynthWaveformSine   sine4;          //xy=350,1950
AudioSynthWaveformSine   sine6;          //xy=376,2149.9998779296875
AudioSynthWaveformSine   sine5;          //xy=377,2099.9998779296875
AudioSynthWaveformSine   sine7;          //xy=379,2200.9998779296875
AudioOutputTDM           tdm2;           //xy=642,1897
AudioOutputTDM2          tdm2_2;         //xy=643,2200.9998779296875

AudioConnection          patchCord1(sine1, 0, tdm2, 0);
AudioConnection          patchCord2(sine1, 0, tdm2, 2);
AudioConnection          patchCord3(sine2, 0, tdm2, 4);
AudioConnection          patchCord4(sine2, 0, tdm2, 6);
AudioConnection          patchCord5(sine3, 0, tdm2, 8);
AudioConnection          patchCord6(sine3, 0, tdm2, 10);
AudioConnection          patchCord7(sine4, 0, tdm2, 12);
AudioConnection          patchCord8(sine4, 0, tdm2, 14);
AudioConnection          patchCord9(sine6, 0, tdm2_2, 4);
AudioConnection          patchCord10(sine6, 0, tdm2_2, 6);
AudioConnection          patchCord11(sine5, 0, tdm2_2, 0);
AudioConnection          patchCord12(sine5, 0, tdm2_2, 2);
AudioConnection          patchCord13(sine7, 0, tdm2_2, 8);
AudioConnection          patchCord14(sine7, 0, tdm2_2, 10);

AudioControlCS42448      cs42448_1;      //xy=366,2039.9998779296875
AudioControlCS42448      cs42448_2;      //xy=378,2353.9998779296875
// GUItool: end automatically generated code




void setup() {
 
  Serial.begin(38400);

 
 
  AudioMemory(1500);
sine1.amplitude(0.3);
sine1.frequency(800);

sine2.amplitude(0.2);
sine2.frequency(1000);

sine3.amplitude(0.2);
sine3.frequency(1200);

sine4.amplitude(0.2);
sine4.frequency(1500);


sine5.amplitude(0.3);
sine5.frequency(800);

sine6.amplitude(0.2);
sine6.frequency(1000);

sine7.amplitude(0.2);
sine7.frequency(1200);

 
  if (cs42448_1.enable() && cs42448_1.volume(0.8)) {
    Serial.println("configured CS42448_1");
  } else {
    Serial.println("failed to config CS42448_1");
  }
 
 if (cs42448_2.enable() && cs42448_2.volume(0.8)) {
    Serial.println("configured CS42448_2");
  } else {
    Serial.println("failed to config CS42448_2");
  }

cs42448_1.inputLevel(5.0);
cs42448_2.inputLevel(5.0);
 
    
}



void loop() {
 
  
}

I have also a trouble if i put a sine generator more ,that makes 8 and the last appears in red in the sketch

I need some advice...
 
There's a discussion on how to wire what looks like the board you have.

cs42448_1 with SCL=19 & SDA=18
cs42448_2 with SCL=24 & SDA=25
They configure ok for the twice

Should i use a different I2S port on the second device,like LCRK_01,BCLK_01,SD_01,SD_IN? And of course I keep MCLK_OUT

I have also a trouble if i put a sine generator more ,that makes 8 and the last appears in red in the sketch
The AudioControlCS42448 object is only written to use the Wire I²C port, which uses SDA/SCL = 18/19. Ideally you should configure one of your CS42448 boards to a different I²C address, and use the undocumented setAddress() function before any other function. As you have it, the "second" call to enable() is just re-enabling the first board... I have no idea if there's a way to do that configuration in the hardware you have ... it'd probably be a couple of jumpers somewhere.

Yes, absolutely you must use the second TDM port for your second device: see post #3 and the Design Tool info pane.

I have no issues placing more than 7 AudioSynthWaveformSine objects - are you sure it's not just outlined in orange because you have it selected?
 
There's a discussion on how to wire what looks like the board you have.


The AudioControlCS42448 object is only written to use the Wire I²C port, which uses SDA/SCL = 18/19. Ideally you should configure one of your CS42448 boards to a different I²C address, and use the undocumented setAddress() function before any other function. As you have it, the "second" call to enable() is just re-enabling the first board... I have no idea if there's a way to do that configuration in the hardware you have ... it'd probably be a couple of jumpers somewhere.

Yes, absolutely you must use the second TDM port for your second device: see post #3 and the Design Tool info pane.

I have no issues placing more than 7 AudioSynthWaveformSine objects - are you sure it's not just outlined in orange because you have it selected?

The fact that the "sine8" was in red is because it is a name in the database of the library or arduino,if i change
a letter it becomes dark-normal :)
There is no jumper i can see to change the address,it's weird,surely no bound to be used in cascade,but is there a logical function
to do that like you point it to:
setAddress()
I would like to make it work and set another address but i don't know how it works,with HEX or DEC?
i'm not experienced enough to read clearly the datasheet.
The TDM port i was talking ,was the pins indexed with _1 of the cs42448 ,not the teensy 4.1 pins,it's strange that the cs42448 has three I2s ports
as we only use the _0 port to have all the inputs & outputs,i think the port _0 is what i should use on the other cs42448,like the first one.

There is that thread where this is discussed: https://forum.pjrc.com/index.php?th...pinouts-and-improved-performance.58836/page-3

I would not like play with:
writeRegCS(CS42448I2C, 0x05, 0x00); // (I2C address, register, setting) Paul's setting = 0x1C

Before i have a confirmation of what it does :cautious:
 
Last edited:
Hi, I have several of these little codec boards, they work well! I planned to try two of them on a single Teensy, but havn't had the time yet, so I'm curious about your project.

I found some docs about these boards. As you see, AD1 and AD0 from the CS42448 are linked to the Master Control pins. On my boards, IC1 and SIP1 are not present. I think they are needed if you want some kind of autoconfig of the board.

Folowing the datasheet of the CS42448, you can connect AD1 to 3.3V through a resistor to have the address 0x4A instead of 0x48. Attention: on my boards, the pin noted 3.3V is indeed not connected, so I had to take 3.3V from the Teensy.


CS42448annoté.jpg
 
Salut le masque!
Well done,you have a better documentation than I,
But i verified the pins and have 3,3V,with the supply coming from the cs42448 usb

ADO - SCL - SDA - UNK - UNK
GND - AD1 - 3,3V - 5V - UNK

Now i understand why AD1 is nearby 3,3V with a jumper,but are you sure you need a resistor?
Have you succeed to change the address yet?
 
Hi! For the 3.3V, I thought of the one on the left row, did not try with the one in the Master Control pins.

For the resistor, this is what is written in the data sheet:
"In I²C Mode, SDA is a bidirectional da ta line. Data is clocked into and out of the part by the clock, SCL.
There is no CS pin. Pins AD0 and AD1 form the two least-si gnificant bits of the chip address and should
be connected through a resistor to VLC or DGND as desired. The state of the pins is sensed while the
CS42448 is being reset. "

It's been a long time ago, but I think I succeded. As h4yn0nnym0u5e said, you have to use "setAddress()" with each of the TDM objects before anything else.
 
thank you lemasque700, i could change the address to AD1->3,3V-> 0X4A and verify it with I2C scanner,
but it's not enough,i looked at:


And change the address:
Code:
cs42448_2.setAddress(0x4A);
cs42448_2.enable();

but both cs42448 failed to configure,the problem seems to be that two I2c's on the same port gives a total failing even the
two addresses are differents, i guess i missed some i2c transactions code.
 
Hi AntiLoop, is all working with only one board and modified address ?

Concerning I2C pull-ups, I could make the I2C connection work without, but as soon as I would add the TDM cables, they become mandatory.
 
Hi,h4n...
I don't think we really need pullups on the SDC & SDA,I2C works and today's boards all incorpore such cms resistors :rolleyes:

Hi,lemasque,yes the cs42448 configure successfully with 0X4A and do not if i change to 0X48​

so the AD1 works fine.
Code:
s42448_1.setAddress(0x4A);//ok
cs42448_1.enable();//ok
Something i found:if you feed with teensy Vin the 5v of the left connector,you have 5v and 3,3v on the control connector
the same if you feed with the cs42448 usb supply.
but nothing seems to be relied to the 3,3v on the left connector,maybe i'm wrong.
You said that IC1 & SP1 are not present,did they say in the datasheet it is possible to control the cs42448
with SPI or I2C?
Maybe h4n... has a better configuration as us because he has a home-made cs42448 board,does it have a better IC to
handle more that a I2C slave?

 
Hi AntiLoop, confirm to work here with two cs42448 boards and two I2C addresses.

I had to add the pull-ups to get it to work. I have no data sheet, but on the schematic (found on the Chinese vendor site), I can see that SCA and SCL are connected directly to cs42448. The internal pull-up of the Teensy are not sufficient. Also you are right, 3.3V on the left is not connected, but you can have it work if you solder R1. Attached is the PCB schematic.

I sometimes had to cut power (unplug and plug USB) so the cs42448 could be initialized the right way. Physically changing the I2C address (AD1 connected to 3.3V or ground) without rebooting has no effect.
 

Attachments

  • CS42448_PCB.pdf
    542 KB · Views: 73
lemasque,you're right ,SCL & SDA have no pullups, all my excuses to h4n...he was right !
But how did you set the addresses?
Did you let cs42448_1 with 0X48 without using setAddress() and AD0, and cs42448_2 using setAddress(0X4A) and AD1-> 3,3V
or did connect AD0 and AD1 to 3,3V and setAddress() to each ones like:

Code:
s42448_1.setAddress(0x48);//ok

cs42448_1.enable();//ok

s42448_2.setAddress(0x4A);//ok

cs42448_2.enable();//ok

personnaly i prefer to let the enable() working in the configurations if(...){} ->edit:i think enable() after setAddress() makes that work

Did you verify if all the inputs & outputs work?

Edit:

I could configure 2 boards with differents addresses without any pullups,but i discover that AD0 doesn't work with 3,3V
if i put it with GND it makes no difference as if it was on the air,but only AD1->3,3V reacts.
 
Last edited:
From what I understand, setAddress() does not send anything to the board, it just tells that the object "cs42448" will use this address to communicate with the board (for enable, setvolume, etc.).

So I set the address physically on the card (AD1 to ground (default, 0x48) or AD1 to 3.3V (0x4A)), then in the code I use setAddress to communicate with this particular board.

Note that you can also set AD0 to ground or 3.3V to set other addresses. To summerize:
AD0 to Gnd and AD1 to Gnd => address 0x48
AD0 to Gnd and AD1 to 3.3V => address 0x4A
AD0 to 3.3V and AD1 to Gnd => address 0x49
AD0 to 3.3V and AD1 to 3.3V => address 0x4B

Unconnected means ground.
 
Sorry about my post just before with some edits without reading you wrote after,but do you still use resistors for Adresses?
I will verify with the I2C scanner...
Edit: i confirm the results and AD0->3,3V extend the combinaisons,don't use any pullups...
 
Last edited:
Based on many years of experience, I would say this: Do What The Data Sheet Tells You To Do. In no particular order:
1722364609463.png

Unconnected does not mean ground - it means unconnected. It may work sometimes, or never, or until you're setting up for the gig of your life. Connect The Pins. Unless you're 110% sure they're connected on the board you have in your hand ... just because the PCB layout has a position for a pull-up or pull-down resistor, that does not mean it's fitted.

1722364965481.png

If you leave a pin floating, noise may cause a transition on AD0, and then the chip is in SPI mode ... until you cycle the power (or possibly just /RST).


1722365253015.png

Make sure you know what /RST is doing. Paul's prototype board had a part fitted specifically to ensure there was a pulse on /RST at power up. You can probably assume that the enable() function takes care of steps 3 onwards...


1722365591829.png

Required means required. Fit The Pullups. Unless you can prove they're already fitted. The Wire driver might (or might not) configure the port pins with pullups, but these are typically too weak to be effective on anything but the simplest of designs.

One final thing which is not datasheet canon, and thus goes against everything I said above :eek:. Some people have had issues which have been resolved by setting an undocumented "magic" bit. This post mentions it, followed by a series of posts later in the same thread. It may be worth trying if you've first done everything the datasheet tells you to.
 
My apologies, I did not mean that not connected generally means ground, I just remembered that ont this board address pins were connected by default to ground, but it 's not the case, so both pins have to be connected. Also, bottom third pin on the Master Control might be attached to Reset on the cs42448 (to be checked).
 
The cs42448 board i own looks the same as lemasque700 and bounded to be mounted with a ADU1452 board,
so components that are not visible on the cs42448 board are certainly fitted on the ADU1452

Here is an entry in alibaba french with more infos than alibaba UK:


Today i will do I2C testing from scratch with 2,2K resistors instead of 10K
The resistors for AD0 & AD1 are they good enough with 10K?

I also have all the ADU1452 and CS42448 together complete documentations but it's 160M0,i don't know if it
allowed as attached files :unsure:
 
Last edited:
components that are not visible on the cs42448 board are certainly fitted on the ADU1452
I'll leave it to you to check that...

The French Alibaba listing doesn't seem relevant to the CS42448 board, apart from it being mentioned in the title. The board is totally different, and as usual there appear to be no links to proper documentation, e.g. a schematic or data sheet.

10K should be OK for setting AD0/1 - the data sheet DC Electrical Characteristics (table on page 24 of the version I have) says the maximum "Leakage current" or Iin is ±10µA, which would give a worst-case low voltage of 0.1V and high of 3.2V, which is the right side of the thresholds of 0.2xVLC and 0.7xVLC.

You should use 2k2 for the SDA/SCL pull-ups - that seems to be the accepted value when using a 3.3V supply.

Yes, I think 160MB would exceed the forum allowance! If you can post a link to the original sources, or put them on a publicly accessible storage like Google Drive or Box, it would be interesting. I can't see any possible justification for the documentation being that big...
 
Back
Top