Audio problem with Nano in TDM slave mode

In my application, I have an FPGA module who is master of the audio clock.
I am pretty confident that this FPGA module is working fine as we already used it in the same configuration on multiple projects.
The FPGA module generate a TDM bus with 16 channels of 32-bit , it has 5 wires connected to the Jetson Nano 40 pin headers:

  • CLK at 22.5792MHz connected to DAP4_SCLK
  • FRAME at 44.1KHz connected to DAP4_FS
  • DATA Out connected to DAP4_DIN
  • DATA In connected to DAP4_DOUT
  • Ground to GND pin 6

Typically everything will works perfectly for may be 1 to 3 hours, I can play and record no problem, audio signals looks/sounds good.
But at some point, the audio time slots get shifted, for example: 0 goes 2, 1 goes to 3, 2 goes to 4, … , 14 goes to 0 and 15 goes to 1.
And it will continue to shift randomly typically every so often.
Looks like the Nano Board sometime loose the frequency lock.

The cable between the FPGA board and Jetson Nano is short ~1.5". I checked the signals on both sides with a scope and they look good.
I tried with different configuration: 44.1KHz, 48KHz, 32KHz, same problem.
I tried with different FRAME signals: Frame high for 1 bit, Frame high for 32 bits and FRAME 50% (I2S like), same problem.

I checked the system logs and dmesg but there is no messages when this is happening.
When the time slots are shifted, I can realign them by typing a few times: “alsactl init tegrasndt210ref”

Here is how I configure ALSA:
alsactl init tegrasndt210ref
amixer -c tegrasndt210ref -q sset ‘ADMAIF1 Mux’ I2S4
amixer -c tegrasndt210ref -q sset ‘I2S4 codec frame mode’ dsp-a
amixer -c tegrasndt210ref -q sset ‘I2S4 fsync width’ 256
amixer -c tegrasndt210ref -q sset ‘ADMAIF1 Channels’ 16
amixer -c tegrasndt210ref -q sset ‘I2S4 Channels’ 16
amixer -c tegrasndt210ref -q sset ‘I2S4 Sample Rate’ 44100
amixer -c tegrasndt210ref -q sset ‘I2S4 codec bit format’ 32
amixer -c tegrasndt210ref -q sset ‘I2S4 input bit format’ 32
amixer -c tegrasndt210ref -q sset ‘I2S4 codec master mode’ cbm-cfm

I also attached some logic analyzer screenshots.

Hello!

Can you tell me how you detect that the slots are shifted? Are you looping the data back out again? If so please let me know how you are doing this.

Looking at the above, I don’t believe you need to set ‘I2S4 fsync width’ at all because the I2S is the slave. My understanding that this is used when the I2S is the master and configures how long the fsync width is. However, I doubt that this is the problem.

When you execute the ‘alsactl init tegrasndt210ref’ it is executing the script in ‘/usr/share/alsa/init/postinit/00-tegra.conf’. It would be interesting so see if there is one particular setting that causes it to realign. You could dump the settings before and after doing this to see the difference to help isolate what is actually changing …

$ alsactl store -f before.txt
$ alsactl init tegrasndt210ref
$ alsactl store -f after.txt

Then diff’ing the before.txt and after.txt will show you what changed and then you can try to determine which of these is making a difference.

Regards,
Jon

Thanks for your reply.
To detect the shifting, looping the data is one way but even simpler is to play continuously on for example channel 1&2, then at some point the signal disappear and looking with a scope I see that the data is now going to for example channel 4&5.

I tried with not setting ‘I2S4 sync width’, same problem.

I looked at the before and after like you mentioned but they are identical.
I attached before.txt

This is strange, looks like something is getting out of sync.
I think this is only happening when the Jetson Nano is slaving to an external clock, I don’t recall seing this when the Jetson Nano is mastering the clock and frame signals, I’ll do more testing.
before.txt (163 KB)

Hello!

Thanks. However, to clarify when you say play continously, you mean that the FPGA is continously playing on channels 1 and 2 and the Jetson is receiving these?

If that is the case and the FPGA is the I2S master, then if the channels swap so that the data is in different slots, isn’t that the FPGA that is swapping the channels?

I know that you said that you have had this working fine with other devices, but if the FPGA is driving both the bit clock and fsync (cbm-cfm), and the data appears to change slot with regard to the fsync signal, then I don’t see how Jetson could be causing this.

Regards,
Jon

Sorry, it is the other way.
The Jetson is playing a file on channel 1&2 of the TDM16, the FPGA convert the TDM16 to eight I2S going to eight stereo DACs, which gives me analog channels 1 through 16. A pair of speakers is connected to analog channels 1&2 and the music is playing.

After a while there is no audio playing coming from the speakers, with a scope I can see that now the Jetson is playing on channel 4&5 with regard to the fsync signal, and if I move the speakers to analog channels 4&5, the music plays again.

Hello!

In that case you shouldn’t be setting …

$ amixer -c tegrasndt210ref -q sset 'I2S4 codec master mode' cbm-cfm

The above is configuring the Jetson I2S as the slave and not master. The above setting is from the perspective of the I2S codec, which in your case would be the FPGA.

BTW, you mean that …

What did you mean by this? Is this the master of the audio clock to the DACs? If so how do you keep the clocks between the Jetson I2S and FPGA in sync?

Regards,
Jon

The audio TDM bus going to the Jetson Nano is bidirectional with 16 channels each way, we use all the channels in both directions.
The Jetson Nano is sending audio to the FPGA and vice versa.

From a clocking point of view, we can have only one master.
The FPGA is the clock master of all the peripherals ADCs, DACs, ADAT, MADI and the Jetson Nano.
This is why the Jetson Nano is in "cbs-cfs’ mode.

Hello!

Thanks. I understand now. The FPGA is the I2S master, but Jetson is playing the audio. How is the audio PCM data being generated for this continously playback? What is the PCM data source or application you are using to provide the data for a few hours of playback?

Have you tried using speaker-test? You should be able to use this to continuously test. This would eliminate any other software causing any delays …

$ speaker-test -D hw:tegrasndt210ref -c 16 -r 48000 -F S16_LE -t sine -f 500

I don’t know if you have there ability to re-build the Linux kernel, but it could be good to the enable the kernel configuration CONFIG_SND_PCM_XRUN_DEBUG and see if any XRUNs are reported.

Regards,
Jon

I use the JACK Audio Framework which is the linux audio low latency framework which runs on top of ALSA.
The JACK framework constantly send and receive the 16 channels of audio.
The JACK framework also reports when they are XRUNs, which I know works because if I choose a frame size too small then I start getting XRUNS.

I did a test with speaker-test and I see the same problem.

Hello!

Thanks for the info. So we can rule out the possibility of any storage media causing delays. Sounds like samples are being dropped somehow. To rule out the possibility of a perf issue can you run the ‘jetson_clocks.sh’ script to run at full speed?

$ sudo ./jetson_clocks.sh

Regards,
Jon

Yes, I am always running at full speed.
This is a strange problem, I have no idea what could be causing this, I will do more testing.