cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 SPI2 Not Receiving Data via DMA Despite Clock Generation.

ajmw_
Associate II

I have an ADC connected to an STM32-L4P5DK. Data should be read in the background by the DMA controller. SPI TX is assigned to DMA1 CHANNEL2, and SPI RX is assigned to DMA1 CHANNEL3. Both DMA1 CHANNEL2 and CHANNEL3 are synchronized with EXTI1 (DRDY signal from the ADC). The STM32 SPI2 is configured as a full-duplex master. Both SPI TX(to transmit dummy bytes) and RX are synchronized with the external interrupt (pin PD1 is assigned to DRDY). 

The problem is that I can see the data on the scope, but SPI2 is not receiving any data.

I start TX using the function:

 

 

HAL_SPI_Transmit_DMA(&hspi2, tx, 0x1b);

 

 

And receive the transmission using:

 

 

HAL_DMA_Start_IT(&hdma_spi2_tx, (uint32_t)adc_buf, (uint32_t)&(SPI2->DR), 0x1b);
SET_BIT(SPI2->CR2, SPI_CR2_RXDMAEN);

 

 

 

DMA1 CHANNEL1, set to very high priority, is used to pull the chip select pin low on the DRDY falling edge. This channel generates a DMA request to control the CS pin.

adc_out.jpeg

Yellow - DRDY from ADC , Green - CS , Red - SCK , Blue - MISO. 

 

SPI RX config:

ajmw__0-1721890010959.png

SPI TX config.

ajmw__1-1721890064626.png

 

Regards,
Aji

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
ajmw_
Associate II

Thank you, @BarryWhit, for your response.

The issue was with the function call. Instead of passing the &hdma_spi2_rx handle, the &hdma_spi2_tx handle was passed.
correct usage:

 

HAL_DMA_Start_IT(&hdma_spi2_rx, (uint32_t)adc_buf, (uint32_t)&(SPI2->DR), 0x1b);
SET_BIT(SPI2->CR2, SPI_CR2_RXDMAEN);

 

 

View solution in original post

5 REPLIES 5
BarryWhit
Lead II

Can you receive data when using the blocking API? try to start simple and make sure things are working, and only then move to DMA.

 

Are you sure you're using the DMA synchronization correctly? the idea is to synchronize incoming DMA request to the synchronizing event. So, something (peripheral, software) is supposed to generate a DMA request (i.e to transfer a word) and this request is only actually forwarded to the DMA peripheral when the synchronization event occurs.

What is generating the DMA requests in your design? 

 

This channel generates a DMA request to control the CS pin.

What do you mean by that? Isn't the DMA configured to move data over SPI? 

- If someone's post helped resolve your issue, please thank them by clicking "Accept as Solution".
- Please post an update with details once you've solved your issue. Your experience may help others.

 

Hi Barry,

Initially, I used the SPI in blocking mode, followed by SPI DMA without synchronization, and both worked fine. However, when I tried SPI DMA with synchronization, I encountered the issue mentioned above.

BarryWhit
Lead II

See my updated response, can you provide more information?

- If someone's post helped resolve your issue, please thank them by clicking "Accept as Solution".
- Please post an update with details once you've solved your issue. Your experience may help others.

> What do you mean by that? Isn't the DMA configured to move data over SPI? 
  No , I am writing GPIOx_BRR register on every falling edge of DRDY signal to reset the chip select pin (active low). All the DMA requests(SPI_TX , SPI_RX and DMA_GENARATOR0) depend on EXTI1

 

	HAL_DMAEx_EnableMuxRequestGenerator(&hdma_dma_generator0);
	HAL_DMA_Start(&hdma_dma_generator0,(uint32_t)&cs_pin,(uint32_t)&(CS_GPIO_Port->BRR),1);

 

then on rising edge of DRDY signal , I am transmitting dummy bytes on tx line to generate clock pulses. So that ADC data can be received. 

DMA request generator config.

ajmw__0-1721896064766.png

 

I am attempting to read 8000 samples per second from the ADC, resulting in a DRDY frequency of 8kHz. On every falling edge of DRDY, a DMA request is generated to make the chip select line LOW. Then, both SPI TX and SPI RX are synchronized with the rising edge of DRDY.

ajmw_
Associate II

Thank you, @BarryWhit, for your response.

The issue was with the function call. Instead of passing the &hdma_spi2_rx handle, the &hdma_spi2_tx handle was passed.
correct usage:

 

HAL_DMA_Start_IT(&hdma_spi2_rx, (uint32_t)adc_buf, (uint32_t)&(SPI2->DR), 0x1b);
SET_BIT(SPI2->CR2, SPI_CR2_RXDMAEN);