cancel
Showing results for 
Search instead for 
Did you mean: 

SPI communication using GPDMA is not working.

Thoufiel
Associate III

I'm using the STM32H562.

The STM side is configured as a slave and is successfully communicating with another board via SPI.

Now, I'm trying to incorporate DMA into the setup, but it's not working as expected.

The transfer complete interrupt is being handled correctly, but the send/receive results are not as expected on either the external board or the STM32 board.

Although fixed values are being transmitted and received, the results are coming out as 0 or 0xFF.

 

The GPDMA configuration is as follows.

(stm32h5xx_hal_msp.c)

/* SPI3 DMA Init */
/* GPDMA1_REQUEST_SPI3_TX Init */
handle_GPDMA1_Channel5.Instance = GPDMA1_Channel5;
handle_GPDMA1_Channel5.Init.Request = GPDMA1_REQUEST_SPI3_TX;
handle_GPDMA1_Channel5.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
handle_GPDMA1_Channel5.Init.Direction = DMA_MEMORY_TO_PERIPH;
handle_GPDMA1_Channel5.Init.SrcInc = DMA_SINC_INCREMENTED;
handle_GPDMA1_Channel5.Init.DestInc = DMA_DINC_FIXED;
handle_GPDMA1_Channel5.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
handle_GPDMA1_Channel5.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
handle_GPDMA1_Channel5.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
handle_GPDMA1_Channel5.Init.SrcBurstLength = 1;
handle_GPDMA1_Channel5.Init.DestBurstLength = 1;
handle_GPDMA1_Channel5.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
handle_GPDMA1_Channel5.Init.TransferEventMode = DMA_TCEM_REPEATED_BLOCK_TRANSFER;
handle_GPDMA1_Channel5.Init.Mode = DMA_NORMAL;
if (HAL_DMA_Init(&handle_GPDMA1_Channel5) != HAL_OK)
{
Error_Handler();
}

__HAL_LINKDMA(hspi, hdmatx, handle_GPDMA1_Channel5);

if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel5, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}

/* GPDMA1_REQUEST_SPI3_RX Init */
handle_GPDMA1_Channel4.Instance = GPDMA1_Channel4;
handle_GPDMA1_Channel4.Init.Request = GPDMA1_REQUEST_SPI3_RX;
handle_GPDMA1_Channel4.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
handle_GPDMA1_Channel4.Init.Direction = DMA_PERIPH_TO_MEMORY;
handle_GPDMA1_Channel4.Init.SrcInc = DMA_SINC_FIXED;
handle_GPDMA1_Channel4.Init.DestInc = DMA_DINC_INCREMENTED;
handle_GPDMA1_Channel4.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
handle_GPDMA1_Channel4.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
handle_GPDMA1_Channel4.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
handle_GPDMA1_Channel4.Init.SrcBurstLength = 4;
handle_GPDMA1_Channel4.Init.DestBurstLength = 4;
handle_GPDMA1_Channel4.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
handle_GPDMA1_Channel4.Init.TransferEventMode = DMA_TCEM_REPEATED_BLOCK_TRANSFER;
handle_GPDMA1_Channel4.Init.Mode = DMA_NORMAL;
if (HAL_DMA_Init(&handle_GPDMA1_Channel4) != HAL_OK)
{
Error_Handler();
}

__HAL_LINKDMA(hspi, hdmarx, handle_GPDMA1_Channel4);

if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel4, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}

/* SPI3 interrupt Init */
HAL_NVIC_SetPriority(SPI3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI3_IRQn);
/* USER CODE BEGIN SPI3_MspInit 1 */
__HAL_LINKDMA(&hspi3, hdmatx, handle_GPDMA1_Channel5);
__HAL_LINKDMA(&hspi3, hdmarx, handle_GPDMA1_Channel4);

-----------------------------------------------------------------------

The SPI transmit and receive is as follows.

void Transceive()
{
    int status1 = handle_GPDMA1_Channel4.Lock;
    int status2 = handle_GPDMA1_Channel5.Lock;
    HAL_DMA_StateTypeDef dma_state1 = HAL_DMA_GetState(&handle_GPDMA1_Channel4);
    HAL_DMA_StateTypeDef dma_state2 = HAL_DMA_GetState(&handle_GPDMA1_Channel5);

    int errorCode1 = handle_GPDMA1_Channel4.ErrorCode;
    int errorCode2 = handle_GPDMA1_Channel5.ErrorCode;
   
    if((dma_state1!=HAL_DMA_STATE_READY) || (dma_state2!=HAL_DMA_STATE_READY)){
        HAL_StatusTypeDef abort_state1 = HAL_DMA_Abort(&handle_GPDMA1_Channel4);
        HAL_StatusTypeDef abort_state2 = HAL_DMA_Abort(&handle_GPDMA1_Channel5);
    }
    HAL_StatusTypeDef status = HAL_SPI_TransmitReceive_DMA(
        &hspi3,                         // SPI3 handle
        TxBuff,                         // Tx Buffer
        RxBuff,                         // Rx Buffer
        sizeof(sizeof(RxBuff)) // Transmit size
    );
}

 

Edited by Moderation to apply source code formatting and add appropriate labels.

1 REPLY 1
Saket_Om
ST Employee

Hello @Thoufiel 

If you are not using repeated block transfer, the TransferEventMode should be set to DMA_TCEM_BLOCK_TRANSFER. Have you used a logic analyzer to verify that the data on the bus is correct ? Also, are the grounds (GND) of the two boards connected to each other?

Please refer to the example below:

STM32CubeH7RS/Projects/NUCLEO-H7S3L8/Examples/SPI/SPI_FullDuplex_ComDMA_Slave at main · STMicroelectronics/STM32CubeH7RS

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.
Saket_Om