I am currently learning STM32F1xx using DMA and SPI with circular mode. My goal is let the STM32F1 to send out same data repeatedly.
I am using cubeMX generated code, setting up the SPI-DMA with circular mode and using HAL_SPI_Transmit_DMA() to activate DMA transmission.
I have a data buffer like here:
char dataBuf[10] = {'a','b','c','d','e','f','g','h','i','j'};
When I use HAL_SPI_Transmit_DMA(&hspi1,dataBuf,10); it works fine. STM32F1 send the characters repeatedly through SPI and I can use HAL_SPI_DMAStop(&hspi1); to stop it.
But If I want just to send 5 byte of dataBuf repeatedly, using HAL_SPI_Transmit_DMA(&hspi1,dataBuf,5), the STM32 can not react on that. It just hanged somewhere and doing nothing.
I am wondering why this is happening. Does the data amount need to be the same as the declared buffer array size (actually, this makes no sense for me)? How can I use circular mode to send desired data amount?
Update1
I should have to attach my SPI and DMA setting, here they are.
SPI setting:
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
DMA setting:
hdma_spi1_tx.Instance = DMA1_Channel3;
hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_tx.Init.Mode = DMA_CIRCULAR;
hdma_spi1_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_spi1_tx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
Update2
This is my test setup with code:
char spiDataBuf[10] = {'a','b','c','d','e','f','g','h','i','j'};
uint8_t runSPI = 0;
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
//HAL_Delay(500);
if(HAL_GetTick()-lastTick > 1)
{
//calColor2Data(&statusColor, 1);
//updateWs2812();
if(runSPI)
{
HAL_SPI_Transmit_DMA(&hspi1,spiDataBuf,5);
// or HAL_SPI_Transmit_DMA(&hspi1,spiDataBuf,10);
runSPI = 0;
}
else
{
runSPI = 1;
HAL_SPI_DMAStop(&hspi1);
}
lastTick = HAL_GetTick();
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
And logic output: When I set 10 bytes to send, it works fine, STM32 send a.b.c... repeatedly and make pause as intended. Logic capture please see follow images.
But When I send 5 bytes, it seems like that it can not be stopped..Logic capture please see follow images.
Send 5 bytes - Overview, can not be stopped
Send 5 bytes - result, but it did send 5 byte repeatedly
My question remains, why the DMA can not be stopped when I set 5 bytes to send?
I did test other number of bytes. 10, 9, 8 bytes work. But 7, 6, 5, 4, 3 ,2 ,1 bytes don't work. SPI DMA is those cases can not be stopped.
If more information needs to be provided, please let me know.
Thanks.
Best regards.