cancel
Showing results for 
Search instead for 
Did you mean: 

Why can't I read from SPI Rx buffer?

Gergo Tanyi
Associate II
Posted on November 02, 2017 at 08:52

Hey guys!

I have an STM32 micro as a Master device, and I am communicating with a slave chip through the SPI interface. It works well, so far I can read from the slave's memory cells, or at least I can see the answer on the oscilloscope. But somehow I'm not able to read out this data from the buffer. I attached  the code, I hope somebody can see what I'm missing. I put it in a loop, which quits when theres any data.

#spi
14 REPLIES 14
AvaTar
Lead
Posted on November 02, 2017 at 09:17

The many busy-loops in this code gives me the creeps.

Have you tried to set a breakpoint after the wait for RXNE, before you try to read the DR register ?

What do you see in DR ?

But somehow I'm not able to read out this data from the buffer

Perhaps your lcdPrintInt() function does not work as expected.

Posted on November 02, 2017 at 09:36

The print function works properly I tested it. As for the busy waits...well I really dont have experience in programming, I just followed exactly the stm32 datasheet, how to use SPI interface, thats why. I havent tried breakpoints, but I will now. And I see only zeros. The while loop would quits if theres something else.

Posted on November 02, 2017 at 09:51

Using your scope, what do you see at the MISO line ?

The SPI interface has several clock polarity and trigger edge options, check with the datasheet of your slave device.

I suspect the slave does not really answer.

Posted on November 02, 2017 at 09:57

Clock vs MISO line. The last 8 bit should be the answer, seems correct.

0690X00000604CKQAY.jpg
Posted on November 02, 2017 at 10:12

Try to start from an example of SPI from the STM32Cube which is from the corresponding board or close one. If speed is paramount, check for Low Layer SPI Master example.

AvaTar
Lead
Posted on November 02, 2017 at 11:19

I would switch to instruction-stepping, i.e. assembler code while debugging.

What are your optimization settings ?

I hope the compiler had not optimized out some of your code ...

Use 'volatile' if in doubt.

Posted on November 02, 2017 at 10:31

At least it is non-zero, and you should be able to read it back.

I would check in the debugger.

If speed is paramount, check for Low Layer SPI Master example.

My concern is less about speed.

Spinning in while-loops to wait for a serial transmit/receive is not very efficient - but you can do it with Cube, LL, or even assembler code.

I have seen such code for 9600 bps UART lines as well.

A DMA base approach or interrupt-based state machine would not waste that much core cycles.

But for an prototype code to test the exact sequence, it would be o.k.

Posted on November 02, 2017 at 11:02

Surely this is just a code, to check on the scope if they communicate at all. I am having troubles setting up the debug session, I cant set any breakpoints, or watch any variable, but this is a different topic, I will manage it.

In any case, what I concluded is that I definitely read 0's from the Rx buffer since the read instruction overwrites the variable spiRecived initialized to be 0xFE, which on the attached code might be zero now.

I also concluded that I do receive answer from the slave, because I checked the memory cells I am reading from, and the data on the scope corresponds to it. So the data is there on the MISO pins but somehow I copy 0's from the Rx buffer.

Im gonna try to setup my debugger, and see whats going on.

Ben K
Senior III
Posted on November 02, 2017 at 14:54

To me it seems that spiReceived value equals to the received byte during your transmission of 0x12, and that's why you get the wrong value. Take a look at TXE and RXNE flag timings in the Reference Manual. Wait for another RXNE flag and see if it resolves your issue.

Edit: I recommend reading and discarding the unused SPI DR values, as some STM32 devices have a FIFO implementation, therefore you might see older values if they have not been read before. This is also good to avoid getting overflow error flags.