Skip to main content
rammit
Senior
April 30, 2020
Solved

Is there a way to change the contents of the SPI TX FIFO?

  • April 30, 2020
  • 16 replies
  • 3334 views

I'm using the SPI peripheral on an STM32H743 as a slave. Is there a way to change the contents of the TX FIFO without resetting the peripheral? I need to always transmit a specifc byte at the beginning of a transaction along with other data, but the master may only request the first byte to analyze it (It is a status word indicating the repsonse is ready). At this point I need to refill the FIFO with the status word and the data.

This topic has been closed for replies.
Best answer by berendi

Clearing and setting SPI_CR1_SPE when NSS goes high should do the trick. It does not reset the configuration.

Bit 0 SPE: serial peripheral enable

This bit is set by and cleared by software.

0: serial peripheral disabled.

1: serial peripheral enabled

When SPE=1, SPI data transfer is enabled, Configuration registers and IOLOCK bit in

SPI_CR1 are write protected. They can be changed only when SPE=0.

When SPI=0 any SPI operation is stopped and disabled, internal state machine is reseted, all

the FIFOs content is flushed, CRC calculation initialized, receive data register is read zero.

SPE cannot be set when MODF error flag is active.

You can configure an EXTI interrupt to be triggered on the NSS rising edge even when the pin is in AF mode, mapped to SPI. Then hope that the master always waits the time needed to run the handler before the next query.

There might be a way to automatize the process with the DMAMUX request generator, EXTI D3 pending clear registers. using one DMA channel to reset/set SPE, and another to refill the FIFO, but noone seems to have figured the request generator out yet.

16 replies

berendi
Principal
May 6, 2020

It is possible with TIM3_CH2 on PA7, but it seems to be more complicated than I have anticipated at first.

So, the basic idea is

  1. TIM3 channel 1 in capture mode, CC1s = 0b10: CC1 channel is configured as input, IC1 is mapped on TI2 which is the TIM3_CH2 pin.
  2. DMA1_Stream0 triggered by the above copies a word containing 0 into SPI4->CR1. NSS rising disables SPI and resets the FIFO.
  3. TIM3 channel 2 in capture mode, CC1s = 0b01: CC2 channel is configured as input, IC2 is mapped on TI2 which is the TIM3_CH2 pin again, but now with inverted polarity (CC2P=1).
  4. DMA1_Stream1 triggered by step 3 copies a word containing SPI_CR1_SSI | SPI_CR1_SPE into SPI4->CR1. NSS falling enables SPI.
  5. DMA1_Stream2 triggered by SPI TX FIFO low threshold copies outgoing data into SPI4->TXDR
  6. An MDMA transfer triggered by DMA1_Stream0 transfer complete event resets DMA1_Stream2 registers.

Is there some minimum time between the rising and falling edge of NSS guaranteed? If it is long enough, then using EXTI would be simpler.

rammit
rammitAuthor
Senior
May 6, 2020

Very impressive. Which DMA stream reads the RX FIFO or is that an unmentioned 4th DMA stream?

I'll use EXTI. There's about 5us of wiggle room.

berendi
Principal
May 6, 2020

Yes, another DMA strem is needed if there is incoming data as well, not just dummy bytes to keep the SPI clock going. That's what bothers me in my solution, using up too many DMA streams from the limited supply.

5 μs should be enough, just use EXTI. Dont't use HAL functions, they are terribly slow. Interrupt handling with HAL is even slower.

rammit
rammitAuthor
Senior
May 6, 2020

That is helpful that you measured HAL's timing in the scope images. HAL gets a lot of criticism, understandably, but in its defense it is VERY handy for getting to know how the peripherals work and have working code that can be extracted.

Do you know anything about JKhal's comment in the "SPI is too slow" forum post you provided a link to about the Hardware NSS not working for him?

berendi
Principal
May 7, 2020

> you measured HAL's timing in the scope images.

Not my measurements, I'm using them with permission. They were made on an STM32F4 which runs maybe on 1/3 the speed of the STM32H7.

> HAL gets a lot of criticism, understandably, but in its defense it is VERY handy for getting to know how the peripherals work and have working code that can be extracted.

Exactly. Look into thje HAL source code to see what registers are in what order accessed. But when dealing with an interrupt that could be triggered in 5 μs intervals, forget fancy concepts like flexible reusable code, write a specialized interrupt handler that does exactly what you require and nothing more.

> about the Hardware NSS not working for him?

No idea. There were issues with hardware NSS in master mode on earlier STM32 series, but I believe they were solved on the STM32H7.

I am not aware of any issues with NSS in slave mode.