SPI with DMA interrupt handling for SPI transfer complete
I'm having trouble understanding how the transfer complete interrupt is working.
I have setup SPI using DMA to speed up data transfer to an LCD-display.
The SPI clock is 18MHz, the System clock is 72MHz.
From the book Mastering STM32 my understanding is that the SPI_TX_COMPLETE_CB should be used to signal the completion.
It is also mentioned that the call back for the SPI is taken care of in the DMA Interrupt.
So I have only enabled DMA Interrupts and no SPI Interrupts.
I have copied large parts of the software and they seem to be using DMA in polling mode.

magenta trace is SPI-CLK
dark blue trace is MOSI/MISO
Here is the main part of the code I am using to produce the scope screendumps:
static void IL9341_WriteData(uint8_t *buff, size_t buff_size)
{
IL9341_Select();
IL9341_DC_Set();
flag=0;
HAL_SPI_Transmit_DMA(&IL9341_SPI_PORT, buff, buff_size);
// while (IL9341_SPI_PORT.hdmatx->State != HAL_DMA_STATE_READY) <== this does not work
// {}
IL9341_UnSelect();
}
void IL9341_Init(void)
{
memset(disp_buf, 0, sizeof(disp_buf)); // fast way to fill buffer with 0
// HAL_Delay(25);
IL9341_RST_Clr();
// HAL_Delay(25);
IL9341_RST_Set();
// HAL_Delay(50);
IL9341_WriteCommand(IL9341_COLMOD); // Set color mode
HAL_GPIO_TogglePin(Test_GPIO_Port, Test_Pin); // Test pin is yellow trace
HAL_GPIO_TogglePin(Test_GPIO_Port, Test_Pin);
IL9341_WriteSmallData(IL9341_COLOR_MODE_16bit);
IL9341_WriteCommand(0xB2); // Porch control
HAL_GPIO_TogglePin(Test_GPIO_Port, Test_Pin);
HAL_GPIO_TogglePin(Test_GPIO_Port, Test_Pin);
{
uint8_t data[] = {0x0C, 0x0C, 0x00, 0x33, 0x33};
IL9341_WriteData(data, sizeof(data));
}
HAL_GPIO_TogglePin(Test_GPIO_Port, Test_Pin);
HAL_GPIO_TogglePin(Test_GPIO_Port, Test_Pin);
}
void spi_tx_complete() {
HAL_GPIO_TogglePin(Diag_GPIO_Port, Diag_Pin); // Test pin is light blue trace
HAL_GPIO_TogglePin(Diag_GPIO_Port, Diag_Pin);
flag=1;
}
int main(void)
{
...
if((HAL_SPI_RegisterCallback(&hspi1,HAL_SPI_TX_COMPLETE_CB_ID,spi_tx_complete)==HAL_ERROR)) {
Error_Handler();
}
while (1)
{
IL9341_Init();
}
}Using the CubeIDE, I have looked at the code in
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c
and
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c
My remaining Questions are:
1) is it correct to register the SPI callback or should I register DMA callback instead?
2) why is there such a long delay in the yellow trace after the DMA-transfer?
It seems that something is stuck in low level (interrupt?) routines
as the end of the yellow trace coincides with the transfer-complete signal (light blue trace)
The delay seems to be similar to the delay between "normal" (non-dma) SPI transactions.
There is no checking with a while(flag==0){;} of the "complete" flag in the IL9341_WriteData routine,
yet it returns after completion. Does this not contradict the use of interrupts? Or is the system just slow?