Skip to main content
Jan1
Associate II
June 27, 2019
Solved

How to avoid unnecessary clocks when receiving data (simplex) from SPI with DMA?

  • June 27, 2019
  • 2 replies
  • 1110 views

STM32F746/Atollic

I want to receive periodically a certain number of bytes from an ADC via SPI using DMA.

Since there is no Tx line, I thought it would be correct to set the SPI at SPI_DIRECTION_2LINES_RXONLY and to program a DMA for Rx. I called this DMA with HAL_SPI_Receive_DMA(&hspi3, SplRxBuff, 33) and expected to receive 33 bytes in SplRxBuff.

My buffer actually receives the 33 bytes but the SPI generates additional clocks which I want to avoid.

In this forum I got the advice to use SPI_DIRECTION_2LINES instead of SPI_DIRECTION_2LINES_RXONLY and to add a Tx DMA even if there is no GPIO for Tx.

I tried to do this but I don't receive any data. What could be wrong?

Here the DMAS for Rx and Tx are set:

/*DMA 1 / channel 0 / stream 0 transfers data from external ADC to sample registers*/
 __HAL_RCC_DMA1_CLK_ENABLE(); /*DMA clock*/
 hdma_spi3_rx.Init.Channel = DMA_CHANNEL_0;
 hdma_spi3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; /*from SPI to memory*/
 hdma_spi3_rx.Init.PeriphInc = DMA_PINC_DISABLE; /*no increment on SPI side*/
 hdma_spi3_rx.Init.MemInc = DMA_MINC_ENABLE; /*increment sample memory address*/
 hdma_spi3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 hdma_spi3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 hdma_spi3_rx.Init.Mode = DMA_NORMAL;
 hdma_spi3_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
 hdma_spi3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
 hdma_spi3_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
 hdma_spi3_rx.Init.MemBurst = DMA_PBURST_SINGLE;
 hdma_spi3_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
 hdma_spi3_rx.Instance = DMA1_Stream0;
 HAL_DMA_Init(&hdma_spi3_rx);
 HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0); /*highest priority for DMA interrupt*/
 HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn); /*enable DMA interrupt*/
 __HAL_LINKDMA(hspi, hdmarx, hdma_spi3_rx); /*link DMA1 to SPI3 Rx*/
 /*DMA 2 / channel 0 / stream 0 sends data to SPI (no GPIO pin existent, only needed for clocking in right number of bytes)*/
 __HAL_RCC_DMA2_CLK_ENABLE(); /*DMA clock*/
 hdma_spi3_tx.Init.Channel = DMA_CHANNEL_0;
 hdma_spi3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; /*from memory to SPI*/
 hdma_spi3_tx.Init.PeriphInc = DMA_PINC_DISABLE; /*no increment on SPI side*/
 hdma_spi3_tx.Init.MemInc = DMA_MINC_DISABLE; /*no increment sample memory address*/
 hdma_spi3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 hdma_spi3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 hdma_spi3_tx.Init.Mode = DMA_NORMAL;
 hdma_spi3_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
 hdma_spi3_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
 hdma_spi3_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
 hdma_spi3_tx.Init.MemBurst = DMA_PBURST_SINGLE;
 hdma_spi3_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
 hdma_spi3_tx.Instance = DMA2_Stream0;
 HAL_DMA_Init(&hdma_spi3_tx);
 __HAL_LINKDMA(hspi, hdmatx, hdma_spi3_tx); /*link DMA2 to SPI3 Tx*/

The DMAs are called here:

/*Data ready interrupt (/ADC_/DRDY) of external ADCs*/
void EXTI9_5_IRQHandler(void)
{
 HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7); /*clear interrupt*/
 HAL_SPI_Transmit_DMA(&hspi3, NULL, 33); /*send dummy bytes via SPI*/
 HAL_SPI_Receive_DMA(&hspi3, SplRxBuff, 33); /*get ADC data*/
}

and the DMA interrupt is never reached:

/*DMA1 stream0 global interrupt (Rx of external ADCs complete)*/
void SPI_DMA_Rx_IRQHandler(void)
{
 HAL_DMA_IRQHandler(&hdma_spi3_tx);
 HAL_DMA_IRQHandler(&hdma_spi3_rx);
 Sampling();
}

This topic has been closed for replies.
Best answer by waclawek.jan

You can't pull DMA channel/stream numbers out of thin air, the DMA triggers in 'F7 are hardwired and Cube/HAL can't magically reassign them.

0690X000009XgB3QAK.png

JW

2 replies

waclawek.jan
waclawek.janBest answer
Super User
June 28, 2019

You can't pull DMA channel/stream numbers out of thin air, the DMA triggers in 'F7 are hardwired and Cube/HAL can't magically reassign them.

0690X000009XgB3QAK.png

JW

Jan1
Jan1Author
Associate II
June 28, 2019

It works! I had missed that.