Restarting an I2S transfer changes alignement in DMA RX buffer

Report here problems in any of ChibiOS components. This forum is NOT for support.
User avatar
Giovanni
Site Admin
Posts: 12296
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 590 times
Been thanked: 504 times
Contact:

Re: Restarting an I2S transfer changes alignement in DMA RX buffer

Postby Giovanni » Fri Jul 27, 2018 3:01 pm

Interesting, that is on the F7 which has a FIFO but flushing the data register after stopping the master clock and DMAs could be a solution. Another option would be to reset the SPI peripheral on i2sStart().

Giovanni

tsichevski
Posts: 35
Joined: Fri Feb 09, 2018 12:44 am
Has thanked: 2 times
Been thanked: 5 times

Re: Restarting an I2S transfer changes alignement in DMA RX buffer

Postby tsichevski » Fri Oct 26, 2018 3:08 pm

I've managed to recover from this problem. Before starting DMA, I explicitly fetch a few half-words from the I2S data register, and find where the sample start sequence begins. Unfortunately, this solution is not universal: is works for my particular codec chip :(

Regards,
Vladimir

User avatar
Giovanni
Site Admin
Posts: 12296
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 590 times
Been thanked: 504 times
Contact:

Re: Restarting an I2S transfer changes alignement in DMA RX buffer

Postby Giovanni » Sun Nov 10, 2019 10:25 am

bump

jpp
Posts: 1
Joined: Fri Nov 29, 2019 10:36 pm

Re: Restarting an I2S transfer changes alignement in DMA RX buffer

Postby jpp » Fri Nov 29, 2019 10:57 pm

Hello,

This is my first post in this forum :)

I think I just ran into this same problem though I did not fully characterized the issue on an STM32F429 (discovery board) and in RX mode.

I found those two links that seem related:
https://community.st.com/s/question/0D5 ... hing-issue
https://community.st.com/s/question/0D5 ... er-restart

So it seems that the issue comes from the fact that when I2S is turned off some data may still arrive into the DR register and those data will get as first data for next reception and shift all the data by 1 channel.

Also I found that ST dedicated a paragraph on "Disabling the SPI" because it is probably a bit tricky and I suppose it applies to the I2S even more.

The interresting sequence they describe is as follow:
- wait for RXNE=1 (this will be the second to last data receive)
- disable the SPI : SPE=0
- wait for RXNE=1 (this is the last)

And this is how I changed the stop_exchange routine:

Code: Select all

void i2s_lld_stop_exchange(I2SDriver *i2sp) {

  /* Stop TX DMA, if enabled.*/
  if (NULL != i2sp->dmatx) {
    dmaStreamDisable(i2sp->dmatx);

    /* From the RM: To switch off the I2S, by clearing I2SE, it is mandatory
       to wait for TXE = 1 and BSY = 0.*/
    while ((i2sp->spi->SR & (SPI_SR_TXE | SPI_SR_BSY)) != SPI_SR_TXE)
      ;
  }

  /* Stop RX DMA, if enabled.*/
  if (NULL != i2sp->dmarx) {
    dmaStreamDisable(i2sp->dmarx);
    while ((i2sp->spi->SR & SPI_SR_RXNE) != SPI_SR_RXNE);
  }

  /* Stop SPI/I2S peripheral.*/
  i2sp->spi->I2SCFGR &= ~SPI_I2SCFGR_I2SE;

  /* Drain the last DATA to clean for next exchange */
  if (NULL != i2sp->dmarx) {
    while (i2sp->spi->SR & SPI_SR_RXNE)
      i2sp->spi->DR;
  }
}


What I believe it could happen before is that:
- Disable SPI : SPE=0
- Disable DMA before that last data arrive
- The last data may arrive but nobody to discard it and let the pipeline clean for next exchange

What I believe it fixes the issue:
- Disable DMA
- Wait for last data (so that we are sure it is here and perhaps preventing other to arrive as there is no buffer)
- Disable SPI : SPE=0
- Drain the last data

This seems to work for me.
Again I don't fully understand what's happening only suppositions.

User avatar
Giovanni
Site Admin
Posts: 12296
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 590 times
Been thanked: 504 times
Contact:

Re: Restarting an I2S transfer changes alignement in DMA RX buffer

Postby Giovanni » Sat Nov 30, 2019 5:59 am

Hi,

Thanks for experimenting with this, I need to look at that paragraph.

The fix makes sense, I wonder if it should go in the SPI driver too when stopping a continuous transfer.

Giovanni


Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 2 guests