cancel
Showing results for 
Search instead for 
Did you mean: 

3-wire SPI Receive - RXNE not working

BenMack99
Senior

STM32G031 SPI in 3-wire half duplex mode. When reading data (BIDIMODE=1, BIDIOE=0), how can I tell when I have clocked in a complete u8/u16?

Neither RXNE or FRLVL appear to get updated until I stop the transaction.

I have it working by using a delay in the code:-

  CLEAR_BIT(SPI2->CR1, SPI_CR1_BIDIOE); // change to Bidirectional input mode
  delay_loop(40);
  SET_BIT(SPI2->CR1, SPI_CR1_BIDIOE);  // change back to Bidirectional output mode
  result = SPI2->DR;

but this seems a nasty cludge

I've RTFM and googled it, seems lots of people have the same problem. The STM32 in 3 wire receive mode just clocks away til you tell it to stop. Surely there's a better way?

Any suggestions gratefully received, thank you

13 REPLIES 13

Hi Chris, yes we are reading using MOSI, in conventional 3-wire half duplex bidirectional mode (BIDIMODE=1, BIDIOE=0). This is clearly documented in the reference manual, so I expected it to work normally, but I can find no explanation as to why RXNE doesn't work in this mode.

> Just seems really weird that RXNE doesn't work in bidirectional rx mode.

How exactly did you test that?

JW

As follows

   while(SPI2->SR & SPI_SR_RXNE)   // clear RX FIFO
      result = SPI2->DR;
   DEBUG_SEL_TP_HI;
   CLEAR_BIT(SPI2->CR1, SPI_CR1_BIDIOE);  // Bidirectional input mode
   while (!(SPI2->SR & SPI_SR_RXNE));   // it sticks here
   //delay_loop(SYSCLK*3-4);   // 20uS delay for 16 bit read @1MHz
   vu32 ben1 = SPI2->SR;
   DEBUG_SEL_TP_LO;
   SET_BIT(SPI2->CR1, SPI_CR1_BIDIOE);    // Bidirectional output mode
   result = SPI2->DR;

(DEBUG_SEL_TP_HO/LO is an output pin I hang a scope on)

With the above code it just sits in the while loop indefinitely.

If I replace the while loop with the delay it works fine. And if I capture SR (see ben1) directly after the delay, RXNE is not set, even though there is complete 16 bit RX data in the DR. RXNE goes hi immediately after setting BIDIOE on line 9, so it appears to be disabled while BIDIOE is 0.

And if I run similar code on a 4-wire SPI then RXNE works fine


@S.Ma wrote:

So far, to have a real world working 3 wire SPI mode, I use 4 wire SPI mode and disable MOSI when reading data in. Most of my other attempt failed.


Disabling MOSI in the 4 wire makes 3 wire, in the sense, i didn't get u.