Discussion:
Channel swapping problem on Atmel SSC audio
Jason Fox
2011-02-17 13:45:20 UTC
Permalink
Hi Everyone,

This seems to be very similar to a problem I wrote about this morning
and i am wondering if a solution was found?

Thank you,
Jason Fox
GAI-Tronics
Reading PA
I had faced the similar issue on IMx31. The cause there was reversal of LRCK clock {180 degree phase shift}.
probing the LRCK clock may help you to find the problem
________________________________________
From: alsa-devel-bounces at alsa-project.org [alsa-devel-bounces at alsa-project.org] On Behalf Of Patrick Ziegler [patrick.ziegler at fh-kl.de]
Sent: Friday, November 12, 2010 1:36 PM
To: alsa-devel at alsa-project.org
Cc: Ryan Mallon
Subject: Re: [alsa-devel] Channel swapping problem on Atmel SSC audio
I'm working on a custom board using the AT91SAM9G45 processor and a
TLV320AIC26 SPI attached audio codec using I2S format audio. When doing
audio playback on the board the left and right channels are occasionally
flipped.
<snip>
Has anybody else had this problem, or does anybody have any AT91/Atmel
hardware that they could test to see if it occurs on other hardware also?
I have worked with the AT91SAM9260 on a project which is currently suspended
(other priorities), where we had a simiar problem, with a codec on SPI.
Every time audio was started (capture or playback) the channels could be
swapped. Solving that issue remains TODO when we restart.
There was a thread on alsa-devel last month 'Soc Atmel SSC stereo problem'
with some suggestions.
Okay, so it's not just me.
In the thread mentioned, Alan proposed me amongst other things to test
the LRCK level before starting the SSC. This works well for me. Maybe it
should be implemented in a more generic way but the following
modification does the trick for me.
+while(!at91_get_gpio_value(AT91_PIN_PB12));
+while(at91_get_gpio_value(AT91_PIN_PB12));
+while(!at91_get_gpio_value(AT91_PIN_PB12));
+while(at91_get_gpio_value(AT91_PIN_PB12));
This appears to work, or at least makes the problem much more rare. I'm
trying to understand if the problem is a silicon bug in the AT91
hardware, or if the DMA start code in the Atmel SoC driver is buggy.

I'm running with the CPU as the master (generating LRCLK and BCLK) and
testing with playback (so CPU is clocking the data out). The TCMR
register has the CKS field set to 0x4 (start on falling edge of LRCLK),
so the above loops should not be necessary. I suspect that the above fix
only makes the problem occur much less frequently, rather than fixing it
correctly?

~Ryan
--
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon 5 Amuri Park, 404 Barbadoes St
ryan at bluewatersys.com PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com New Zealand
Phone: +64 3 3779127 Freecall: Australia 1800 148 751
Fax: +64 3 3779135 USA 1800 261 2934
*******************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom
they are addressed. If you have received this email in error please
notify the system manager. This footnote also confirms that this
email message has been swept for the presence of computer viruses.
www.Hubbell.com - Hubbell Incorporated**
Peter Ujfalusi
2011-02-18 07:06:13 UTC
Permalink
Hi,
Post by Jason Fox
This appears to work, or at least makes the problem much more rare. I'm
trying to understand if the problem is a silicon bug in the AT91
hardware, or if the DMA start code in the Atmel SoC driver is buggy.
I'm not familiar with the Atmel platform, but we have had similar
channel swap/shift problems (random channel swap at stream start) in
OMAP3 McBSP.
In our case it was due to the fact, that OMAP3 McBSP has two bits to
actually enable the digital interface.
The early code enabled this two bit at the same time, and that was the
root of the problem.
This is what happened:
- DMA has been configured, and started (HW synchronized DMA, McBSP
requests the DMA to push data)
- McBSP got enabled, and got released at the same time
McBSP immediately signaled the DMA to push data.
Depending on the timing, there were cases, when McBSP started to send
out the data, while the DMA has not pushed anything to McBSP FIFO.
So the first word was 0, and the second was the first word from the
sample -> channels swapped.
This has happened in McBSP slave configuration as well: depending on the
timing of the McBSP start we have seen random channel swap.
If the McBSP was enabled just right before the start condition on the
I2S bus, it sent out 0 for the first word, and than the audio data ->
channel swapped.
We have fixed this by first enabling the McBSP, but keeping it
unreleased state. When McBSP is enabled, it will trigger DMA to start
pushing data, so we have valid audio data in the FIFO.
We wait for 500us.
We release the McBSP. At this point it will either start listening for
the start condition on I2S bus (slave), or start the clocks on the bus.
Since we already had the valid audio data in the FIFO, the channel swap
has gone.

I suppose you also have similar issue.
Other solution which we considered could have been used only in case of
16bit/stereo audio:
Configure McBSP for 32bit word length (and single slot) in case of
16bit/streo audio. When the race happens McBSP would have sent 0 for
both channels, so we would not have the channels swapped. But this will
only work with 16bit/stereo mode - and mono as well ;)

So we sticked with the former solution.

I hope this helps for you to figure out something similar for your problem.
--
Péter
Loading...