Spi clock accuracy

I’ve discover today that spi clock in settings is not really accuracy:

Clock has been set to :

_spiDevice = SpiDevice.FromId(Pins.BrainPad.Expansion.SpiBus.Spi1, new SpiConnectionSettings(Pins.BrainPad.Expansion.GpioPin.Rx)
        ClockFrequency = 400000,
        DataBitLength = 8,
        Mode = SpiMode.Mode0

I check hardware with I2c and it is correct on timing:

I2c clock has been set to:

            _device = I2cDevice.FromId(Pins.BrainPad.Expansion.I2cBus.I2c1, new I2cConnectionSettings(0x2c)
                BusSpeed = I2cBusSpeed.FastMode,
                SharingMode = I2cSharingMode.Shared

SPI on STM32 is woriking with only a “set” of frequencies. Those frequencies are calculated using a prescaler whose value is in the SPI_CR1_BR_0 to SPI_CR1_BR_2 registers.

So, depending on the MCU and its running frequency, you won’t get exactly the frequency you set/require but something more or less approaching.
See below :

// Peripherial Clock 42MHz SPI2 SPI3
// Peripherial Clock 84MHz SPI1                                SPI1        SPI2/3
#define SPI_BaudRatePrescaler_2         ((uint16_t)0x0000) //  42 MHz      21 MHZ
#define SPI_BaudRatePrescaler_4         ((uint16_t)0x0008) //  21 MHz      10.5 MHz
#define SPI_BaudRatePrescaler_8         ((uint16_t)0x0010) //  10.5 MHz    5.25 MHz
#define SPI_BaudRatePrescaler_16        ((uint16_t)0x0018) //  5.25 MHz    2.626 MHz  
#define SPI_BaudRatePrescaler_32        ((uint16_t)0x0020) //  2.626 MHz   1.3125 MHz
#define SPI_BaudRatePrescaler_64        ((uint16_t)0x0028) //  1.3125 MHz  656.25 KHz
#define SPI_BaudRatePrescaler_128       ((uint16_t)0x0030) //  656.25 KHz  328.125 KHz
#define SPI_BaudRatePrescaler_256       ((uint16_t)0x0038) //  328.125 KHz 164.06 KHz

This means that if you change the MCU’s clock and keep the same prescaler value, you won’t get the same SPI frequency at the end.

I2C is using fixed frequencies, so there are no calculations.


Thanks for this “accurate” answer :slight_smile:

From what I understand of SPI this is a non-issue ( unless you have very specific requirements other than achieving communication ).

The Master dictates the speed of transfers by creating the clock signal. All the Slave must do is handle its operations on each clock edge and be prepared to do it again on the next clock edge. There is no need to agree on what the speed will be or anything like that.

Almost true… The speed selected by the master must be less than or equal to the maximum speed of the slowest device on the bus.

1 Like

Hmm. I think I disagree here. For one part this is kind of what I was getting at in that the Slave device must be able to complete it’s operation and be ready for another operation before the next clock edge.

The other part I think makes this not really the case is that you can reconfigure the clock speed for the device you wish to communicate with for a specific transaction. If you have one master and two slaves where one is fast and one is slow, then you can switch between faster and slower clock speeds between transfers.

The slow device won’t get out of whack when the clock is fast assuming it implements the bus correctly, i.e. it doesn’t care what happens on MISO, MOSI, or CLK as long as SS is deasserted for this device.

What has been your experiences when assuming something? :slight_smile:

Assuming things has created time warps in which hours of my life are pulled into a blackhole and I’m not released until I finally realize my assumptions clouded my judgement.

Let’s just say the slow device will ALWAYS be out of whack until you verify that it isn’t! Much safer.

1 Like

@Mike’s point was just that sometimes certain slave devices don’t support clock speeds that new (master and slave) devices are capable of. If you try to use a speed higher than that slave device can handle, you’re in uncharted waters usually orbiting said blackhole. If you use the highest supported speed by all devices, you should work (programming aside :wink: )…

If the CLK wonders ‘a little’ that wouldn’t cause any great issues would it?
As long as it doesnt go below or above the valid timing theasholds.
As its just used as an edge clk trigger to clock data in out., not really to keep accurate timing.

absolutely, clock variance is typically a non-issue in SPI. You can even bit-bang it within speed limits of slave, even with timing jitter. That’s why an externally clocked signal is often preferred to one that must have a shared / known timing accuracy (eg the RS232 baud rate selection problem)

1 Like

I can’t imagine that an apparently simple question can unchain so many “literature”. But it is what what I love with this community: you learn each day something ! :wink:


This is a reason why i love forum since you learn a lot from peoples experiences regards their problems which we faced too.

So I ,like an pure very beginner learn a lot things here
Thanx to @Justin, @Gus_Issa , @dobova and reading between lines of code (which in literature you can not find those great tricks)


We have learned many things ourselves on this forum. So thanks to you and to all the great contributors


Also, the impedance of the CLK line will also limit the clock speed. Then there is propagation delay. Long lines at high speeds can end up being transmission lines and as such suffer from propagation delay. Once device works find but the others do not. Whenever possible, measure the rise and fall times from the source to the furthest device on the chain.

And don’t get me started on reflections :frowning:

1 Like

Here’s a good start :joy: