cancel
Showing results for 
Search instead for 
Did you mean: 

How to clear SPI TX Buffer

ilhyoungkim
Associate
Posted on January 02, 2012 at 04:06

I am using STM32F103 MPU.

I set the board as SPI Slave and uses DMA to receive and send data.

Most of time Command comes from Master and Slave responses.

So I made code to wait for receiving Command from Master. Once Command is received, send response back to Master. This approach is working.

But, really trouble is that, rarely, Slave needs to send data to Master without command.

In that case, I disable DMA RX, TX buffer and canceled waiting Command.

After that, SPI is reinitiated with DMA RX, and TX buffer with new data to be sent to Mater.

When I took a look the signal log, the first byte to be sent to the Master is always from dummy value which was in previous waiting Command transaction.

Even I canceled waiting Command transaction, 1 byte still remains in TX buffer.

I tried to find a way how to clear TX buffer in STM32F103 reference manual, I couldn't find it.

Anybody has any idea how to clear TX buffer?

#stm32f103 #spi
6 REPLIES 6
ColdWeather
Senior
Posted on January 02, 2012 at 13:54

Look at chapter 25.3.8 on page 693 from Reference Manual RM0008.PDF (Doc ID 13902 Rev 12) to disabling SPI.

ilhyoungkim
Associate
Posted on January 03, 2012 at 04:43

ColdWeather, Thank you.

But, it doesn't really work for me. The disabling steps are below.

In master or slave full-duplex mode (BIDIMODE=0, RXONLY=0)

1. Wait until RXNE=1 to receive the last data

2. Wait until TXE=1

3. Then wait until BSY=0

4. Disable the SPI (SPE=0) and, eventually, enter the Halt mode (or disable the peripheral

clock)

But, TX buffer is not empty, the logic cannot go further after step #2.

I need to find a way to force to TX buffer clear, or some how drain it.

jpnorair2
Associate II
Posted on January 09, 2012 at 00:09

I can't be sure, but I have a good guess how to solve your problem.  You are using a DMA transfer complete (TC) interrupt, right?  In this interrupt service routine (ISR) you must not disable the SPI.  The SPI has a bit FIFO buffer and a shadow register buffer.  So, there is a two-word buffer, and when DMA reports TC, there are still two words left.  When you disable the SPI in the DMA TC ISR, the rest of the FIFO will empty, and then it will get filled again with the shadow register.

What you need to do is turn-on the SPI TXE interrupt in your DMA TC ISR.  Then the SPI TXE interrupt should occur twice.  On the second time, you can disable the SPI because the TX is completely done and the buffer is empty.

This is an ugly interface, but to use SPI with DMA on STM32, this is how it is done.

However, there is another way (a total hack).  Make a TX DMA process (which you have done) and also an RX DMA process.  This way, the SPI will be terminated when everything is done, and only the DMA interrupt needs to be monitored.

- Set SPI to full duplex.

- Set RX DMA to ''Circular'' mode.

- Use some 1-word memory space for the RX buffer (it is a dummy)

- Set RX DMA to same length as TX DMA

- Use the RX DMA TC interrupt as the end state.

dejanpojbic
Associate II
Posted on April 16, 2014 at 17:11

Hi,

None of both solution work for me. Only SPI_deInit help. But if I do deInit inside CS interrupt routine, CS interrupt is always called. 

CS and RDY are set as GPIOs.

My STM32F207 is in slave mode. DMA is set to TC interrupt. 

I can create this error, by after transmit is done, i write something to DR reg and then always get a byte shift on next normal transition. In reality, it looks like, i get a glitch on the line, therefore one byte is not send.

Is there of no other solution for his issue? All i want is to empty registers TX and RX before DMA starts to send.

christams9
Associate
Posted on January 14, 2015 at 16:21

Hi,

Did you reach a resolution to this problem ?

I am having something very similar with SPI between two STM32F437's.

re.wolff9
Senior
Posted on June 30, 2016 at 16:03

Did you find a solution to this problem? I'm having a very similar problem on an STM32F0xx....