cancel
Showing results for 
Search instead for 
Did you mean: 

SPI back to back writes

Uwe Bonnes
Principal III

Hello,

setting up STM32L412 SPI for 16 bit Spi transfer and doing:

   uint16_t *SPI_DR = (uint16_t*)&SPI1->DR;

   *SPI_DR = 0;

//   while (~SPI1->SR & SPI_SR_TXE) {NutSleep(0);}

   *SPI_DR = 0;

results in only 16 bit shifted out. With the check for TXE enabled, 32-bits are shifted out as expected. FRXTH is set to 0: RXNE event is generated if the FIFO level is greater than or equal to 1/2 (16-bit)

The registers are CR1 = 0x34d, CR2 = 0xf00, SR = 0x2

I did not find any restrictions in back to back write in the datasheet. PCLK is 16 MHz. But it seems the second write is ignored. I don't see an errata regarding this issue too.

1 ACCEPTED SOLUTION

Accepted Solutions
Bob S
Principal

Your SPI_DR pointer is not flagged as "volatile" (specifically, "pointer to volatile"), are your sure the 2nd "*SPI_DR = 0" isn't getting optimized out when the while() line is commented out?

View solution in original post

6 REPLIES 6
Bob S
Principal

Your SPI_DR pointer is not flagged as "volatile" (specifically, "pointer to volatile"), are your sure the 2nd "*SPI_DR = 0" isn't getting optimized out when the while() line is commented out?

S.Ma
Principal

If you really want to directly write registers, don't use local variable like this.

In debug mode, go assembly view and see it for yourself.

For educational purpose, disable compiler optimisation is a short relief, not a cure.

Uwe Bonnes
Principal III

Good ideas. Will try tomorrow.

> I did not find any restrictions in back to back write in the datasheet.

There's also no encouragement for it.

It probably takes time until the datum written to holding register gets transferred into the shift register; or to start the clock generator; or to shift within the empty FIFO; or any delay for whatever internal reason. Probably a couple of SPI input clocks (i.e. respective APB clocks).

TXE is there for a reason.

JW

Uwe Bonnes
Principal III

Volatile did the trick! Thanks

I've just tried on a 'L476 DISCO and the back-to-back write appears to work, so the problem may be in the writes being optimized out as other have said.

JW