cancel
Showing results for 
Search instead for 
Did you mean: 

Accurate timing of events - SPI DMA

sreyas40
Senior

sreyas40_0-1762943386543.png

In the above image (logic analyzer) , SPI in DMA was supposed to start at the end of high on the second signal, but it starts a bit later. (3rd signal CS of SPI, 4th signal SCLK)

sreyas40_1-1762943518981.png

And the SPI was to supposed to be active at every period (the first signal) whose period is 8.607us. 

The second signal is a slave timer to the first and a period elapsed callback of this signal call HAL_SPI_Receive_DMA.

There is also a 1 second timer

sreyas40_2-1762943888502.png

What should i do to correct this? I don't how to proceed, any solutions, learning materal would be really helpful

6 REPLIES 6
Imen.D
ST Employee

Hello @sreyas40 

I advise you to follow the SPI example and available with STM32CubeH7 MCU package, which shows how to perform SPI data buffer transmission/reception between two boards via DMA:

Eg:STM32CubeH7/Projects/NUCLEO-H743ZI/Examples/SPI/SPI_FullDuplex_ComDMA at master · STMicroelectronics/STM32CubeH7 · GitHub

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
TDK
Super User

> SPI in DMA was supposed to start at the end of high on the second signal, but it starts a bit later. (3rd signal CS of SPI, 4th signal SCLK)

There will always be some delay between the event and SPI starting, especially if you're doing it with the CPU as in the code. If you're transmitting a few bytes, you could use DMA to reduce this, but not eliminate it.

If you feel a post has answered your question, please click "Accept as Solution".

@Imen.D 

The example gave me a few more ideas to improve the code, earlier i wasn't checking the state of SPI state before calling again.

sreyas40_0-1763011809216.png

Now during a cycle SPI triggers at same time and finishes before next cycle, but from the interrupt it takes 6.5us to trigger SPI in DMA mode. Why is it taking that much time, i dont have anything else going on in the code, i haven't even written logic to process the receieved values. 

sreyas40_1-1763012048292.png

And it's still not getting triggered for every cycle, anything else to look out for

 

edit: i don't think it worked because initially at the moment of start ,spi happens within the cycle, but with time spi creeps into the next cycle :(

 

 

 

@TDK 

I'm using SPI in DMA , but as of now , it takes 6.5us to start SPI , that's a bit long right.

CPU at 480MHz

If HAL is not fast enough, you can try compiling with higher optimization settings. If that is insufficient, you will need to write your own driver.

You haven't specified what is good enough. It will never be 0 us, so what is sufficient? Unclear how the "trig" variable is getting set. You could be losing all your time there--between it getting set and calling HAL_SPI_Receive_DMA. I suggest toggling a pin just before calling HAL_SPI_Receive_DMA to measure the approximate delay native to HAL_SPI_Receive_DMA.

If you feel a post has answered your question, please click "Accept as Solution".

@TDK 

Well i need it to start within a maximum of 300ns of calling HAL_SPI_Receive_DMA.

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ 
	if(htim == &htim4){
		trig = 1;
	}

	if(htim == &htim7){
		trig_1sec_d = 1;
	}
}
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  if(trig){
		  trig = 0;
		  if (hspi3.State == HAL_SPI_STATE_READY){
			  HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
			  HAL_SPI_Receive_DMA(&hspi3, (uint8_t*)adc_val, DATA_COUNT);
		  }
		}

	  if(trig_1sec_d){ // to get samples/sec
		  count_1sec = count;
		  count = 0;
		  trig_1sec_d = 0;
		}

  }

 I tried as you suggested, toggling a GPIO before SPI, It takes around ~5us after callback.

Is there a way to achieve what i'm aiming for, to trigger SPI without calling in software