cancel
Showing results for 
Search instead for 
Did you mean: 

Stm32mp157c Spi Dma Transfer Stuck Problem

aliMesut
Associate III

Hello,

I am working stm32mp157c. I want to send the data coming from ipcc to m4 to another chip with spi.

My code is;

void MX_SPI4_Init(void)
{
 hspi4.Instance = SPI4;
 
 hspi4.Init.Mode = SPI_MODE_MASTER;
 
 hspi4.Init.Direction = SPI_DIRECTION_2LINES_TXONLY;
 
 hspi4.Init.DataSize = SPI_DATASIZE_8BIT;
 
 hspi4.Init.CLKPolarity = SPI_POLARITY_LOW;
 
 hspi4.Init.CLKPhase = SPI_PHASE_2EDGE;
 
 hspi4.Init.NSS = SPI_NSS_HARD_OUTPUT;
 
 hspi4.Init.BaudRatePrescaler =  SPI_BAUDRATEPRESCALER_8;
 
 hspi4.Init.FirstBit = SPI_FIRSTBIT_MSB;
 
 hspi4.Init.TIMode = SPI_TIMODE_DISABLE;
 
 hspi4.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 
 hspi4.Init.CRCPolynomial = 0x0;
 
 hspi4.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
 
 hspi4.Init.NSSPolarity = SPI_NSS_POLARITY_HIGH;
 
 hspi4.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
 
 hspi4.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
 
 hspi4.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
 
 hspi4.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
 
 hspi4.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
 
 hspi4.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
 
 hspi4.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
 
 hspi4.Init.IOSwap = SPI_IO_SWAP_DISABLE;
 
 if (HAL_SPI_Init(&hspi4) != HAL_OK)
 {
  Error_Handler();
 }
 
}
 
 
 
void MX_DMA_Init(void)
 
{
 /* DMA controller clock enable */
 
 __HAL_RCC_DMAMUX_CLK_ENABLE();
 
 __HAL_RCC_DMA2_CLK_ENABLE();
 
 
 
 /* DMA interrupt init */
 
 /* DMA2_Stream0_IRQn interrupt configuration */
 
 HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 1, 0);
 
 HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
 
 /* DMA2_Stream1_IRQn interrupt configuration */
 
 HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 1, 0);
 
 HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
 
}
 
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
 
{
...
 
/* SPI4 DMA Init */
 
  /* SPI4_TX Init */
 
  hdma_spi4_tx.Instance = DMA2_Stream1;
 
  hdma_spi4_tx.Init.Request = DMA_REQUEST_SPI4_TX;
 
  hdma_spi4_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
 
  hdma_spi4_tx.Init.PeriphInc = DMA_PINC_DISABLE;
 
  hdma_spi4_tx.Init.MemInc = DMA_MINC_ENABLE;
 
  hdma_spi4_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 
  hdma_spi4_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 
  hdma_spi4_tx.Init.Mode = DMA_NORMAL;
 
  hdma_spi4_tx.Init.Priority = DMA_PRIORITY_LOW;
 
  hdma_spi4_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
...
 
}
 
int main()
{
 
MX_SPI4_Init();
MX_DMA_Init();
 
VIRT_UART_Init(&huart0);
VIRT_UART_RegisterCallback(&huart0,  VIRT_UART_RXCPLT_CB_ID, data_receive)
 
while (1)
{
...
}
 
}
 
void data_receive(VIRT_UART_HandleTypeDef *huart)
 
{
uint8_t buffer[1000] = { 0 };
 
 uint16_t recSize = huart->RxXferSize < MAX_BUFFER_SIZE ? huart->RxXferSize : MAX_BUFFER_SIZE-1;
 
memcpy(buffer, huart->pRxBuffPtr, recSize);
 
if (GL.spi[SPI_MOD]->State == HAL_SPI_STATE_READY)
{
 
HAL_SPI_Transmit_DMA(buffer, buf_addr, MPEGTS_PACKET_SIZE);
 
}
 
}
 

As the data size from ipcc(data_receive) increases, hal_spi_transmit_dma stucks. But when i use hal_spi_transmit instead of hal_spi_transmit_dma stuck does not occur.

Why do you think hal_spi_transmit_dma could cause such a thing?

Best Regards,

Mesut Ince

13 REPLIES 13
PatrickF
ST Employee

Hi @aliMesut​ ,

did you progress on a more stable solution ?

Regards.

In order to give better visibility on the answered topics, please click on 'Select as Best' on the reply which solved your issue or answered your question. See also 'Best Answers'

In order 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.
aliMesut
Associate III

Hİ @PatrickF​ 

Thank you for your suporting. But there was no improvement.

Regards.

Hi @PatrickF​ ,

I put a delay of 100 microseconds between the data, the problem does not appear for now. But it was not a good solution. Problems may arise in the future

Regards.

Hi,

I still recommend that instead of testing directly SPI HAL state like you mention:

if (&hspi4>State == HAL_SPI_STATE_READY)

you implement cleaner way using HAL_SPI_TxCpltCallback() interrupt.

such:

    bool volatile DMA_Finished = true;
    .......
    if (DMA_Finished == true)
    {
    DMA_Finished = false;
    HAL_SPI_Transmit_DMA(buffer, buf_addr, MPEGTS_PACKET_SIZE);
    }
    ......
     
    void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
    {
    DMA_Finished = true;
    }

Regards.

In order 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.