waclawek.jan

I2S slave WS-synchronisation mechanism

Discussion created by waclawek.jan on Sep 13, 2017

(Continuation/generalization of I2S slave lost syncronization  )

 

In the SPI/I2S modules' chapter of STM32F4 RMs (probably other families too but I am not going to investigate), I am missing a concise description of the I2S slave behaviour with regard to WS.

 

There are several options:

 

a) I2S starts shifting as soon as it's enabled, regardless of WS's state, and as soon as the preset number of bits is counted, it performs the "store/load" (stores the received data from shift to Rx holding register and vice versa loads the fresh data from Tx holding to shift register). This would be plain wrong and I doubt this is what any STM32 I2S incarnation does.

 

b) after enable, shifting is not enabled immediately, but as soon as WS is at "active" level, the shifting starts - and the rest is the same as above, i.e. after fixed number of shifts the "store/load" is performed, regardless of WS.

 

c) after enable, shifting is not enabled immediately, but as soon as WS transitions from "inactive" to "active" level, the shifting starts, and the rest is the same as above.

 

d) after enable, shifting is not enabled immediately, but as soon as WS transitions from "inactive" to "active" level, the shifting starts. If the prescribed number of bits is shifted in, shifting stops; regardless of this, when the expected next transition on WS occurs, the "store/load" is performed and shift is resumed (all this respecting the one-bit WS-edge-to-data lag in true-Philips I2S). This is the right way to implement I2S slaves, as it allows flexible data-width-to-WS-width ratios, as well as automatic next-word recovery from bit shifts caused by noisy clocks/glitches.

 

 

IMO, in the original STM32F4xx line (i.e. 'F405/407/415/417/427/429/437/439 , documented in RM0090), b) holds. This is confirmed by the the "In I2S Slave mode, WS level must be set by the external master when enabling the I2S" erratum in the various 'F4xx errata.

 

This has been fixed/upgraded to one of the c) or d), i.e. true-edge-sensitive WS, in the newer 'F4, such as 'F446 (I will use this and related RM0360 in this text as a replacement for "newer 'F4xx" and "all RMs for these newer ''F4xx" - where I say "fix this in RM0360" I mean "fix it in all related RMs" of course).

 

Together with this upgrade, a new configuration bit appeared, SPI_I2SCFGR.ASTRTEN. Setting this bit probably restores the "original 'F4xx" behaviour.

 

Findings:

1. SPI_I2SCFGR.ASTRTEN is misspelled in all 3 places in RM0390 as ASTREN (one T missing) - in errata and CMSIS-mandated headers in Cube it's spelled ASTRTEN and I guess this is the proper spelling. In RM0390 and AN4658 it's IMO misspelled with the missing T. IMO It's important to keep names consistent across documentation (and libraries/code) to facilitate textual search.

 

2. In RM0390, there's no mention of ASTRTEN (or ASTREN) other than the bit's description in "26.7.8 SPI_I2S configuration register (SPI_I2SCFGR)" (There's no more relevant info in AN4658). The explanation for ASTRTEN=1 says, "When the I2S is enabled in slave mode, the I2S slave starts immediately the transfer when the I2S clock is received from the master without checking the expected transition of WS signal." This is IMO plain wrong, see a) above; and I don't believe this is the real behaviour. The wording of the "In I2S Slave mode, with Bit ASTRTEN=1, WS level must be set by the external master when enabling the I2S" erratum confirms this.

 

3.IMO the description of ASTRTEN should mention not only the working but also the *reason* for this bit, namely backward compatibility with the original F4xx line. It's even more logical to be found in AN4658.

 

4. Most importantly, the narrative in SPI/I2S chapter should clearly state, which of the cases a)..d) holds, i.e. whether after initial synchronisation WS is ignored or not.

 

Thanks,

 

Jan Waclawek

 

 

 

Outcomes