cancel
Showing results for 
Search instead for 
Did you mean: 

How to use HAL_SPI_TransmitReceive_DMA API in STM32F429 & CubeMX Library,

edmond yun
Associate II

Hi,

I have some trouble to handle ADS7953 with HAL_SPI_TransmitReceive_DMA api,

if using HAL_SPI_TransmitReceive api, it takes long time and impact other operations,

so I hope to reduce the communication time with HAL_SPI_TransmitReceive_DMA in the communication of SPI, please help to let me know the method if possible, with detailed example,

I update my code, please help to review it, if finding something, please help to let me know what I should modify and how to modify with detailed example or explanation,

Thankful for your kindness in advance,

thanks.

My code is,

CS_Low;

    if(HAL_SPI_TransmitReceive_DMA(&hspi2, cmd, data, 2) != HAL_OK) {

/* Transfer error in transmission process */

    }

uint8_t state = HAL_SPI_GetState(&hspi2);

while (state != HAL_SPI_STATE_READY) {

state = HAL_SPI_GetState(&hspi2);

Hal_DebugPrint("SPI2_HS1_ManulMode hspi2 State is: %d\r\n", state);

}

CS_High;

and the setting case of SPI & DMA is,

/* USER CODE BEGIN SPI2_MspInit 0 */

/* USER CODE END SPI2_MspInit 0 */

__HAL_RCC_GPIOI_CLK_ENABLE();//love_0718

/* Peripheral clock enable */

__HAL_RCC_SPI2_CLK_ENABLE();

/**SPI2 GPIO Configuration   

PI3   ------> SPI2_MOSI

PI2   ------> SPI2_MISO

PI1   ------> SPI2_SCK 

*/

GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_1;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;

HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);

/* SPI2 DMA Init */

/* SPI2_TX Init */

hdma_spi2_tx.Instance = DMA1_Stream4;

hdma_spi2_tx.Init.Channel = DMA_CHANNEL_0;

hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;

hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_spi2_tx.Init.MemInc = DMA_MINC_ENABLE;

hdma_spi2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

hdma_spi2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

hdma_spi2_tx.Init.Mode = DMA_NORMAL;

hdma_spi2_tx.Init.Priority = DMA_PRIORITY_LOW;

hdma_spi2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

if (HAL_DMA_Init(&hdma_spi2_tx) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

__HAL_LINKDMA(hspi,hdmatx,hdma_spi2_tx);

/* SPI2_RX Init */

hdma_spi2_rx.Instance = DMA1_Stream3;

hdma_spi2_rx.Init.Channel = DMA_CHANNEL_0;

hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;

hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_spi2_rx.Init.MemInc = DMA_MINC_ENABLE;

hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

hdma_spi2_rx.Init.Mode = DMA_NORMAL;

hdma_spi2_rx.Init.Priority = DMA_PRIORITY_LOW;

hdma_spi2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

if (HAL_DMA_Init(&hdma_spi2_rx) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

__HAL_LINKDMA(hspi,hdmarx,hdma_spi2_rx);

/* DMA controller clock enable */

__HAL_RCC_DMA1_CLK_ENABLE();

/* DMA1_Stream4_IRQn interrupt configuration */

HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 1, 0);

HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);

/* DMA interrupt init */

/* DMA1_Stream3_IRQn interrupt configuration */

HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 1, 0);

HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);

thanks.

3 REPLIES 3
Amel NASRI
ST Employee

Hi @edmond yun​ ,

A detailed example is available under STM32Cube_FW_F4_V1.21.0\Projects\STM32F429I-Discovery\Examples\SPI\SPI_FullDuplex_ComDMA. It shows how to perform SPI data buffer transmission/reception between two boards via DMA.

HAL_SPI_TransmitReceive_DMA is used there.

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

edmond yun
Associate II

Hello, @Amel NASRI​ ,

Firstly Thankful for your reply,

I would like to delivery what I did for this issue in a few days ago,

please help to refer it and to let me know the detailed example to solve this issue,

thankful for your support in advance,

  1. I already tried to use the example for ADS7953, but failed every time, when checking the data, all is not correct, channel number is not sequence, it has strange value,

frankly speaking, I don't know the method to use the example for ADS7953,

and I should use ADS7953 as a manual mode, can't probably use auto mode, I need to select the channel every time, in this case, I wonder whether DMA mode can't support ADS7953 in manual mode or not, please help to know your opinion for this question,

thanks.

amelendez
Associate III

Dear Edmond.

Did you want to communicate to Amel?.

Sorry to say that this is amelendez​, not Amel NASRI.

Best regards.