Issues with SAI I2S DMA Callback Firing one Frame Too Early on KL27

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Issues with SAI I2S DMA Callback Firing one Frame Too Early on KL27

1,441 Views
2bluesc
Contributor II

Hi all,

 

I have a KL27 with a SGTL5000 audio codec using the I2S SAI peripheral using Kinetis SDK 2.1.  I'm able to setup and send data as expected, but the DMA transfer seems to fire the callback exactly one I2S frame too early.

 

I suspect that the DMA callback fires when all the data is written to the FIFO, but the FIFO hasn't been written out the serial line yet.  The DMA callback in the fsl_sai_dma driver then disables the I2S transmitter and it appears that the last frame is stuck in the FIFO.  If I repeat the transfer, the last frame appears immediately on the wire and the problem repeats.

 

I've captured this with my scope to confirm my suspicions:

174820_174820.pngSAI DMA Missing Frame.png

 

If I modify `SAI_TransferAbortSendDMA()` and comment out the the `SAI_TxEnable(base, false);` line so that the I2S transmitter stays enabled then the last byte shows up on the scope, but something is broke and subsequent transfers fail and I haven't debugged this yet, but I suspect a SAI FIFO error:

174869_174869.pngSAI DMA All Frames with TX left Enabled.png

 

Does anyone have a solution to this?  It seems that disabling the SAI transmitter needs to be delayed until after the last frame is on it's way out as opposed to sitting in the FIFO.

Labels (1)
2 Replies

1,079 Views
2bluesc
Contributor II

I worked around this by turning on the FIFO empty warning IRQ in the DMA About Send function instead of disabling the the transmitter.  In the FIFO empty warning call back I then disable the transmitter and it works as expected.

I threw together a patch to share.  Hopefully NXP can implement an improved version in to the next SDK release or suggest a better solution.

Working scope trace:

NewFile36.png

Link to Github gist of the patch.

1,079 Views
javiercardona
Contributor III

Hi Kyle,

I had a similar problem when using DMA to transfer data over SPI.  I only needed to transmit data and turn off the SPI Chip Select line after that.  The DMA callback would get called right after the last byte hit the FIFO, and before the byte made it over the bus.  This would result in the CS line being de-asserted too soon.

In this case the solution was simple: providing an RX buffer would delay the time at which the callback was invoked.  Would a solution like that work in your case?

Best,