cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 SPI HAL Driver very slow

Alex Wagner
Associate
Posted on November 03, 2017 at 16:43

Hi, I am using Keil and STM32F769I-Eval board.

I try to readout a sensor with an external ADC (AD7980). The signal I try to convert runs with 200kHz.

I generate with a timer every 5us an interrupt. With the interrupt I start the ADC and want to read back the values.

But after the end of the SPI transmission, there is a gap of 3.3us. This gap is to long. So I only get every second value.

0690X00000608p6QAA.png

yellow: SPI_CLOCK

green: GPIO_PIN_7

HAL_SPI_Receive(&hspi3, AD7980_RECEIVED ,2,1);

inter=0;

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);

This is the code behind the scope above.

Is there a way to make this gap smaller?

I looked for a way to write my own routine to receive data. But I wasn't successful.

Kind Regards

Alex

4 REPLIES 4
Posted on November 03, 2017 at 17:19

>>

I looked for a way to write my own routine to receive data. But I wasn't successful.

You looked unsuccessfully, or wrote one and weren't more successful?

Did you try to use the registers and wait on SPI->SR.RXNE ?

Probably don't want to be using blocking code in the interrupt either.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Alex Wagner
Associate
Posted on November 03, 2017 at 17:40

uint8_t SPI3_send(uint8_t data)

{

uint32_t start_time_r;

uint32_t this_time_r;

SPI3->DR = data; // write data to be transmitted to the SPI data register

while( !(SPI3->SR & SPI_FLAG_TXE) ); // wait until transmit complete

while( !(SPI3->SR & SPI_FLAG_RXNE) ); // wait until receive complete

while( SPI3->SR & SPI_FLAG_BSY) // wait until SPI is not busy anymore

 {

 this_time_r = HAL_GetTick() - start_time_r;

 if (this_time_r > 5000)

 {

// timeout error!

 break;

}

return SPI3->DR; // return received data from SPI data register

}

}

I tried this. But it doesn't work. It isn't sending any clock or datas. 

When I debug the code, it never leaves the second while loop. 

S.Ma
Principal
Posted on November 03, 2017 at 18:25

Use SPI 4 wire mode (16 clocks?)

If using a timer to make the conversion pulse at 200kHz, control the duty cycle to be right when the conversion is supposed to be completed. Then make an interrupt on that output compare falling edge event.

In the interrupt, read the SPI DR and back-it up in a buffer, then write on the SPI DR kick 16 bit SCK periods, no need to wait for its completion, the read will be done at next sample kick off.

This is a wild guess to make the interrupt as short as possible considering a pipeline flow of incoming data.

Posted on November 05, 2017 at 12:15

Did you init start time before entering the loop?

Start from a working spi example closest to your needs. Spi goes so fast we usually never need to wait in milisecond range. Don t use a so long delay under interrupt. It will cause more pain than cure to yout problem. What you need is a spi rxne interrupt.