2025-01-13 05:44 AM - last edited on 2025-01-13 07:11 AM by SofLit
Hi!
I am working on a project where we are using DMA driven SPI-transmissions. I am using LPTIM1 to synchronize readouts of multiple SPI busses.
The setup works when the transmissions is equal or below 128 bits (for SPI1-SPI3).
When HAL_DMA_MuxSyncConfigTypeDef.RequestNumber is above 4 (at DMA_PDATAALIGN_WORD and DMA_MDATAALIGN_WORD) it will not work.
From what I can understand this is due to the size of the fifo registers of the SPI-peripheral.
Is there a workaround for this?
This is my current setup:
DMA_InitTypeDef txDMAinit;
DMA_InitTypeDef rxDMAinit;
spiHandle.Init.Mode = SPI_MODE_MASTER;
spiHandle.Init.Direction = SPI_DIRECTION_2LINES;
spiHandle.Init.DataSize = SPI_DATASIZE_32BIT;
spiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
spiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
spiHandle.Init.NSS = SPI_NSS_HARD_OUTPUT;
spiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
spiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
spiHandle.Init.TIMode = SPI_TIMODE_DISABLE;
spiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
spiHandle.Init.CRCPolynomial = 0x0;
spiHandle.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
spiHandle.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
spiHandle.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
spiHandle.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
spiHandle.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
spiHandle.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_04CYCLE;
spiHandle.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
spiHandle.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
spiHandle.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
spiHandle.Init.IOSwap = SPI_IO_SWAP_DISABLE;
if(HAL_SPI_Init(&m_spiHandle)!= HAL_OK)
{
return StatusCode::STATUS_ERROR;
}
txDMAinit.Direction = DMA_MEMORY_TO_PERIPH;
txDMAinit.PeriphInc = DMA_PINC_DISABLE;
txDMAinit.MemInc = DMA_MINC_ENABLE;
txDMAinit.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
txDMAinit.MemDataAlignment = DMA_MDATAALIGN_WORD;
txDMAinit.Mode = DMA_CIRCULAR;
txDMAinit.Priority = DMA_PRIORITY_MEDIUM;
txDMAinit.FIFOMode = DMA_FIFOMODE_ENABLE;
txDMAinit.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL;
rxDMAinit.Direction = DMA_PERIPH_TO_MEMORY;
rxDMAinit.PeriphInc = DMA_PINC_DISABLE;
rxDMAinit.MemInc = DMA_MINC_ENABLE;
rxDMAinit.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
rxDMAinit.MemDataAlignment = DMA_MDATAALIGN_WORD;
rxDMAinit.Mode = DMA_CIRCULAR;
rxDMAinit.Priority = DMA_PRIORITY_MEDIUM;
rxDMAinit.FIFOMode = DMA_FIFOMODE_ENABLE;
rxDMAinit.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL;
pSyncConfig.SyncSignalID = HAL_DMAMUX1_SYNC_LPTIM1_OUT;
pSyncConfig.SyncPolarity = HAL_DMAMUX_SYNC_FALLING;
pSyncConfig.SyncEnable = ENABLE;
pSyncConfig.EventEnable = DISABLE;
pSyncConfig.RequestNumber = 8;
hdma_spi1_tx.Instance = DMA1_Stream4;
hdma_spi1_tx.Init = txDMAinit;
hdma_spi1_tx.Init.Request = DMA_REQUEST_SPI1_TX;
HAL_DMA_Init(&hdma_spi1_tx);
if((HAL_DMAEx_ConfigMuxSync(&hdma_spi1_tx, &pSyncConfig)) != HAL_OK)
{
return StatusCode::STATUS_ERROR;
}
__HAL_LINKDMA(&m_spiHandle,hdmatx,hdma_spi1_tx);
hdma_spi1_rx.Instance = DMA1_Stream1;
hdma_spi1_rx.Init = rxDMAinit;
hdma_spi1_rx.Init.Request = DMA_REQUEST_SPI1_RX;
HAL_DMA_Init(&hdma_spi1_rx);
if((HAL_DMAEx_ConfigMuxSync(&hdma_spi1_rx, &pSyncConfig)) != HAL_OK)
{
return StatusCode::STATUS_ERROR;
}
__HAL_LINKDMA(&m_spiHandle,hdmarx,hdma_spi1_rx);
It only works for pSyncConfig.RequestNumber <= 4.
Any suggestions for a workaround would be appreciated!
Best regards,
Hans-Petter
2025-01-13 07:08 AM
> it will not work
Elaborate.
JW
2025-01-13 07:11 AM
@HansPLJ please use </> button to paste a code. See this post. I've edited your post