cancel
Showing results for 
Search instead for 
Did you mean: 

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

rammit
Senior

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.

1 ACCEPTED SOLUTION

Accepted Solutions
berendi
Principal

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.

View solution in original post

16 REPLIES 16
berendi
Principal

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.

rammit
Senior

Thanks! I think you also answered another question I have. So even when the NSS pin is in AF mode, mapped to SPI, can it also be configured an EXTI interrupt?

berendi
Principal

Yes, the GPIO input side including EXTI works even if the pin is in output mode (think open-drain outputs) or AF mode. (I'm not sure about analog mode though)

rammit
Senior

Is there a trick to receiving data when the SSM bit is set to 0?

"SSM: software management of SS signal input

0: SS input value is determined by the SS PAD"

The GPIO mode for that pin is set to GPIO_MODE_IT_RISING.

I'm not receiving data in slave mode when this bit is 0. I verified the CS signal to the MCU is going low externally.

Read out and check SPI registers content and also all relevant pins GPIO register settings.

What exactly are the symptoms, how do you know SPI does not receive? Did you observe also the clock and data pins?

JW

berendi
Principal

The GPIO pin should be in alternate function mode, assigned to the SPI NSS function. EXTI configuration is independent of the GPIO, the pin mapping and interrupt mask for EXTI can be set in the SYSCFG and EXTI peripherals. HAL might not be able to handle this configuration, because it wants to configure all of them at once, but the registers can be set directly.

But I've got another idea.

Connecting the chip select line to a timer capture input, it is possible to trigger DMA transfers on both edges to the SPI CR1 register. It can disable both SPE and SSI on the rising edge, and enable them on the falling edge. Then another DMA transfer triggered by the empty SPI FIFO can refill it with the data at the time when the request comes from the master, not when the previous request is finished.

rammit
Senior

Thx berendi. This is helpful. I'll probably implement solution 1. You resolved some confusion I had about EXTI and HAL. Would I set the GPIO mode for the NSS pin to GPIO_MODE_AF_PP or GPIO_MODE_AF_OD?

The second solution is intriguing. It might take me while to figure out how to set that up because I haven't used the timer captures before. In our board design I have SPI4_NSS connected to PE4 which is muxed with TIM15_CH1N. Will this work to generate a capture interrupt?

In analog mode, the input buffer is disabled. Analog voltages not near GND or VCC of the buffer will cause large current in the input buffer

berendi
Principal

> You resolved some confusion I had about EXTI and HAL. 

HAL is confusing, and will confuse you even more. One of the reasons I'm not using it. The other is the useless documentation.

> Would I set the GPIO mode for the NSS pin to GPIO_MODE_AF_PP or GPIO_MODE_AF_OD?

Slave NSS is an input-only function, where the push-pull or open-drain settings don't matter.

> SPI4_NSS connected to PE4 which is muxed with TIM15_CH1N. Will this work to generate a capture interrupt?

No, CH*N pins are output-only, it would only work on a TIM*_CH* pin without the N. It also requires a timer with DMA trigger on capture capability, and at least 2 channels (but only one pin has to be connected). So if you decide to go for it and patch or redesign the board, connect it to an input channel of TIM1 to TIM5, TIM8, TIM12 or TIM15.

It might be possible to use the SAI1_FS_A mode on PE4, trick SAI1 to forward the signal to TIM2_ETR (through TIM2->AF1) and/or to one of the LP timers, and trigger a DMA request from there. I'll try to figure it out.