cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L151CBT6 SPI Full-Duplex as slave: Problems understanding SPI DMA and how to use it

Chrizzly
Associate III

Hello, in my setup the STM32L151CBT6 (32MHz) is configured as slave of a PLD Master, which provides a 4MHz Clk for the SPI communication.

After a short "handshake" between slave and PLD where the slave sends and receives some bytes (with HAL_SPI_Transmit and HAL_SPI_Receive in a while loop until a specific handshake value is received) for confirmation that it had a successfull "start-up" phase the master then starts sending 64Byte Data packages in a cyclic manner.

In previous tests I (with the help of the forum Einstein TDK) came to the conclusion that the HAL_SPI_TransmitReceive function is to slow. So now I want to use the HAL_SPI_TransmitReceive_DMA function. When I just use the HAL_SPI_TransmitReceive_DMA function in a while loop in my main function I see (on a digital oscilloscope) that my master and slave send the right Dummy values in correct order.

My slave should have a 400µs window between each received package to manipulate data.

To test if my slave receives the right data during the operational phase I wanted it to copy the received data and send it out in the next package cycle.

I think the problem lies in the lack of understanding how to use the HAL_SPI_TransmitReceive_DMA function properly. Maybe someone can explain how I get my test setup working and how to use the HAL_SPI_TransmitReceive_DMA function the right way (and even if I can use it for my use case)?

I posted the simple main while loop for my Test setup, which does not work. It aborts the slave sending part afer the 1st byte.

  while (1)
  {
 
 
   HAL_SPI_TransmitReceive_DMA(&hspi1, Configuration_Values_Tx, Configuration_Values_Rsx, 64);
    
   for (iter_i =0; iter_i < sizeof(Configuration_Values_Rsx); iter_i ++)
    {
      Configuration_Values_Tx[iter_i] = Configuration_Values_Rsx[iter_i];
    }
   
    
  }

12 REPLIES 12
Chrizzly
Associate III

Thank your for your answer!

I followed your advice.

I changed SPI DMA back to normal mode.

I set the breakpoint in the if condition.

Result:

The programm did not enter the if condition.

After the transmission of the initial package with the numbered bytes array (Configuration_Values_Tx[64] = {1, 2, ..., 64 }) was sent the following 64Byte packages had a value of "64" for each byte (like the "64_Problem_Package_2_01" screenshot).

Purpose of my code:

The purpose of my code is to get the communication right so I can continue implementing the remaining functionality of my slave device.

I want to get the communication straight before I continue implementing anything else.

  while (1)
  {
    if(data_rec){
      data_rec=false;
      for (iter_i =0; iter_i < sizeof(Configuration_Values_Rsx); iter_i ++)
      {
        Configuration_Values_Tx[iter_i] = Configuration_Values_Rsx[iter_i];
      }
      if(data_rec){
        too_fast_checker = false;      // set Breakpoint here
      }
    }

Maybe your trouble is not synced start. When you call

HAL_SPI_TransmitReceive_DMA(&hspi1, Configuration_Values_Tx, Configuration_Values_Rsx, 64);

your link on SPI need be without trafic. But when Master sends your data will bad and not sync...

You need add some waiting for pause.

Better is when Slave send requst IRQ to master and this start send based on it.

And from your images isnt clean Data is valid on rising or failing clock edge ? Is SPI set to this?

And when you go back to normal DMA you need restart it in code for too fast check. I dont see in your code restart. ...

Chrizzly
Associate III

Thank you MM for your advice!

I didn't realize my clock phase was wrong. I changed it to second edge.

I configured DMA to circular.

After the configuration process the slave responds with a 0x02 indicating that it is ready.

  1. The 1st Package is my initial dummy 64 Byte Array
  2. The 2nd Package should be the received data from the 1st transmission, but the 1st byte of the seconde package is always 01.
  3. The 3rd Package and the following Packages are correct.

The 01 could be from the 1st package where the dummy values are sent, but why? The 3rd and following packages don't show this behavior?

Can I use the function HAL_SPI_Transmit() and HAL_SPI_Receive() during my configuration Process before using SPI DMA in circular mode?

0693W00000GY9SQQA1.png0693W00000GY9SGQA1.png0693W00000GY9RhQAL.png0693W00000GY9RXQA1.png0693W00000GY9RNQA1.png0693W00000GY9R8QAL.png0693W00000GY9QKQA1.png