STM32 gotchas
177.I2SxExt allows not only fullduplex SPI, but also dual-Tx/dual-Rx

SPI/I2S is a combined module in STM32, which extends the SPI functionality with I2S (and similar audio protocols) capability. At the end of the day, I2S is a similar shift-register-like protocol as SPI is. Not all incarnations of SPI module implement also the I2S functionality, but in most STM32 families around half of the SPI modules present in given model do.

The SPI functionality is implemented as full-duplex, i.e. there are two data pins, one for input and one for output; and they even can swap direction as required by master or slave role. However, quite inexplicably, the I2S functionality in the same module is implemented only as simplex1.

This means, that there is only one data pin available in I2S mode, set to either input (for audio recording) or output (playback) as required. However, audio CODECs - i.e. chips which contain both an ADC and a DAC - usually have two data pins - one dedicated for input and one dedicated for output - while they share a single set of clock signals (SCK (data/bit clock, sometimes denoted as BCLK), WS (word-select clock, sometimes denoted as LRCK for left-right clock), and in some cases a high-frequency master clock MCLK). This means, that to use such chip, especially when recording and playing back simultaneously, two SPI/I2S units have to be employed, and their respective WS and SCK pins have to be mutually interconnected. If the STM32 is to play master role in this connection, it would need to generate the clocks in one of the SPI/I2S units (i.e. have it set as master), and the other unit needs to be set as slave. It does not matter, whether it's a master transmitter and slave receiver, or vice versa, master receiver and slave master (with the respective data pins connected to the CODEC's data pins as appropriate for their direction). If the CODEC or some third connected device generates the clocks, both SPI/I2S units in STM32 would need to be set as slaves.

As interconnecting pins externally means wasting a precious resource, ST worked around this problem in some STM32 families2 by attaching a second, simplified, unit to the SPI/I2S units, called I2SxExt (where x matches the number of its respective SPI/I2S unit, e.g. I2S3Ext is attached to the SPI3/I2S3 unit). I2SxExt is the same design as SPI/I2S, except it's simplified by having its SPI and master (clock generation) capabilities removed. It has its SCK and WS pads internally attached to the SCK/WS pads of its respective SPI/I2S counterpart. It means, that I2SxEXT has only its data pad exposed through GPIO to a pin, so together with its SPI/I2S counterpart they provide the fullduplex I2S capability.

In short, I2SxExt is functionally an identical unit to I2S/SPI (with functionality restricted to slave I2S), exactly in the same way as with two separate I2S/SPI with interconnected clocks, except that it has its SCLK and WS signals connected to its respective SPIx/I2Sx unit internally.

One consequence of this fact is, that - same with two separate I2S/SPI with interconnected clocks - the I2S/I2SExt couple does not necessarily need to be set up as fullduplex, i.e. with one unit set as input and other as output. Sometimes, the application requires to have two simultaneous outputs or two simultaneous inputs (i.e. four audio channels in the same direction). The I2SxExt+SPI/I2S combo is perfectly capable to handle this situation, too.


1. ... except in 'H7. However, the SPI/I2S unit in 'H7 is an overcomplicated design, very different from SPI/I2S in other STM32.

2. 'F3 and 'F4, although not in all models of these families, e.g. 'F410 has no I2SxExt. In the newer 'F7, 'L4, 'G4 families, where audio capability is expected, while simplex I2S is still retained in some SPI/I2S models, the primary method of interfacing audio codecs (including fullduplex) is through the SAI unit.