2017-04-18 02:28 AM
Hi,
I am trying to configure the STM32F7 to work with a Timer and a SPI to transfer data using DMA.
The idea is to use the TIM6 to trigger the SPI so I start the SPI data transmission inside the timer interrupt handler (HAL_TIM_PeriodElapsedCallback) and wait for the SPI transmission complete interrupt there.
After some test I found that the SPI transmission complete interrupt is not working and the problem seems to be the nested interrupts (SPI inside the TIM6 handler).
How should I configure the NVIC to make nested interrupts work?
Thanks in advanced,
Omar
#timer #interrups #nvic #stm32f7 #spi #dma2017-04-18 05:21 AM
You need to use the preemption levels (on the Cortex low numbers mean higher priority). You need to set the NVIC grouping so it supports the mix of preemption and sub-priorities you need. Here SPI must preempt TIM
The HAL has grave problems with blocking in interrupts, ie it is possible very easily to have code in interrupt handlers that spins unnecessarily, and has the potential to dead-lock. I would be very wary of such code, and the potential side-effects.
2017-04-19 02:43 AM
Thanks for help.
If I understood well then I should assign lower priority to SPI (DMA), so I did this for the DMA:
HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 0,0);
HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
and this for the TIM6:
HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 1,0);
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
But still doesn't work. The code is still waiting for DMA to complete the transfer indefinetely.
2017-04-19 06:31 AM
This is the code inside the TIM6 Callback function to handle the overflow interrupt.
The code is indefinetely waiting in the 'while' loop. I attach this for clarity.
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ // EnvÃo de datos por el SPI al DAC // Si no hemos llegado al final del buffer if (cnt <= 31000){ // Seleccionamos el DAC con el CS // TODO // Transmitimos el siguiente byte de la LUT if(HAL_SPI_Transmit_DMA(&hspi2, (uint8_t*)LUTDAC[cnt], BUFFERSIZE) != HAL_OK){ // TODO Error_Handler(); } // Esperamos a que se haya realizado la transmisión while (wTransferState == TRANSFER_WAIT) { } // Deseleccionamos el CS // TODO cnt++; // Siguiente dirección de la LUT }}2017-04-19 04:26 PM
Hi,
you have to set flags under interrupt, and poll those flags in the foreground.
then you wont have any trouble.