kledtke.steve.002

STM32L476RG SPI clock, initial state HI despite CPOL=0

Discussion created by kledtke.steve.002 on Jun 14, 2017
Latest reply on Jun 30, 2017 by waclawek.jan

Hallo,

I have a nucleo STM32L476RG board and a Kionix KX122 accelerometer board connected via 4-wire SPI.
I set up the nucleo board thus:

SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; // 2.5 MHz from 80 MHz base

SpiHandle.Init.Direction = SPI_DIRECTION_2LINES;

SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;

SpiHandle.Init.DataSize = SPI_DATASIZE_16BIT;
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE;
SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SpiHandle.Init.NSS = SPI_NSS_SOFT;        // SPI_NSS_HARD_OUTPUT;
SpiHandle.Init.NSSPMode = //SPI_NSS_PULSE_DISABLE;   // SPI_NSS_PULSE_ENABLE;  

SpiHandle.Init.Mode = SPI_MODE_MASTER;

The first test was with NSS soft, i.e. I configure the NSS pin as GPIO PP, manually set it low before calling HAL_SPI_TransmitReceive(...), and set it to high again after the call.

 

On the logic analyzer it can be seen that happening:

  • CS gets drawn low
  • SPI SCK is initially HI
  • after a while, SCK gets low
  • after another pause, clocking of the frame starts

The possible problem with that is that the slave (the KX122) sees a high clock first, after !CS is drawn low. According to the logic analyzer, this is against protocol. And it certainly does not look like the timing diagram of the KX122 demands:

As clearly visible, CLK is low at the beginning.
While the STM32L4 has it high initially, repeatably. But when transmission started, it does do a "active hi" clock as expected, just that the initial state is wrong.
So to remedy this, I tried the HARD-Out NSS config, i.e. the STM32L4 SPI HW doing the CSing. There, it looks like the clock gets to low barely before CS gets asserted, a few µs, which should be enough.
There, I at least do get some data bytes back from the slave when trying to configure it.
Alas, it's "garbage", and replies at he wrong places.
The thing is: I did successfully confiure and read data from the same KX122 accelerometer using a MCP2210 USB<-->SPI bridge module before, and basically using the same code now on the STM32, just that the SPI backend is different. The SPI configuration should be the same (only 16bit vs. 8bit frames, but using 8bit frames on the stm32, too, does not help, and as you see from the timing diagram, 16 bit frames should be optiomal due to the {registerAddr; registerValue} format).

Right now I am trying to detect differences in the MCP2210 SPI logic analyzer readout vs. the STM32 one, which is not easy as the MCP module leaves huge pauses (millisecs) between transmissions, so it's hard to compare visually.
What *can* be seen is that the MCP does have the CLK low from the very beginning. But that shouldn't make a difference as long as he lowers CLK before the slave is selected, right?

So:

  • What about the soft NSS (which I'd prefer*), can this be gotten right, i.e. with correct initial CLK=low, or does this work with hard NSS only?
  • Any further ideas what could be wrong in my hard NSS config?


Thanks in advance for your hints!


P.S. I'd prefer soft NSS because I'd not have to reconfigure the SPI mode between pulse and not pulse when I want to write/read commands to the KX122 vs. doing many-bytes read bursts with constantly asserted CS without resending the register address, which the KX122 supports for getting the data buffer. How well this reconfiguring is going to work with regards from what the SPI outputs then really do then, is also still in question

P.P.S. hey, this editor is working much better than months ago when I last posted!

Outcomes