cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_SPI_Receive returns TIMEOUT in ThreadX and touchgfx

fernandogamax
Associate III

Hello.

I have created a project with STM32H7, and in the project, I have included TouchGFX and ThreadX.

I have an external memory controlled by SPI5. Everything works correctly. However, on some occasions, the function:

 

status = HAL_SPI_Receive(hspiDFW25, bufferRX, bytes_to_read, 1000);

returns TIMEOUT.

If I give higher priority to the task where the HAL_SPI_Receive function is called than to the TouchGFX task, the error occurs less frequently. However, it still persists.

Any ideas?

15 REPLIES 15
fernandogamax
Associate III

Are all of your interrupts currently at the same priority?

I have tried them. And the same problem continues. 

 

Is you code running from external memory?

My code runs in internal memory. the touchgfx framebuffer, I have it in external ram

 

 
I have executed a basic project. Containing: Threadx,USBx,FILEx,touchgfx.
I'm just generating a task. And the problem continues.
 
I have tried. with interruption, and in this semaphore waiting for the interruption, it returns TX_NO_INSTANCE. only on some occasions.
 

void Actualiza_remota_Init(void)
{

            tx_thread_create(&thread_actualiza_remota_ptr, "ACTUALIZA_REMOTA",
                  Actualiza_remota_tarea, 0x1234,
                  thread_actualiza_remota, DEF_RAM_THEAD_ACTUALZA_REMOTO,
                 30,30,TX_NO_TIME_SLICE,
                 TX_AUTO_START);

}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
                 tx_semaphore_put(&sem_prueba);
}

void Actualiza_remota_tarea(ULONG id)
{
            HAL_StatusTypeDef status;
            UINT estado_sem;
           estado_sem=tx_semaphore_create(&sem_prueba, "sem_prueba", 1);
           uint32_t temp32;
           while(1)
             {

                       HAL_SPI_Receive_IT(&hspi5, buffer_spi, 2048);
                      estado_sem=tx_semaphore_get(&sem_prueba,1000);
                     if(estado_sem!=TX_SUCCESS)
                     {
                           consola_LIB_send_string("ERROR SPIFLASH no recive");
                      }
                     tx_thread_sleep(10);
}

fernandogamax_0-1707828249949.png

 
I attach the .ioc. in case you can help me.
fernandogamax
Associate III

The only interrupts that are being executed are:

void LTDC_IRQHandler(void)
{
HAL_LTDC_IRQHandler(&hltdc);
}

void DMA2D_IRQHandler(void)
{
HAL_DMA2D_IRQHandler(&hdma2d);

}

void OTG_HS_IRQHandler(void)
{
HAL_HCD_IRQHandler(&hhcd_USB_OTG_HS);
}

> Are all of your interrupts currently at the same priority?

> I have tried them. And the same problem continues. 

This may be a language thing again - do you mean that you have tried assigning different priorities to each interrupt source?  And made the SPI interrupt this highest priority (lowest priority number)?

 

I really don't know how else to say this: USE DMA!  HAL_SPI_Receive_IT() still requires one interrupt per byte.

Do you have any code for the HAL_SPI_ErrorCallback()?  It may be possible that you are getting an overrun if one of the other interrupts takes more than one SPI byte's worth of time to execute.

fernandogamax
Associate III

Hello, new tests

I have managed to make it work using HAL_SPI_recive_IT and HAL_SPI_recive_DMA.

But I can't get it to work HAL_SPI_recive.

The solution has been the priority of the interrupts. Configuring them as follows:

fernandogamax_0-1707992317631.png

I would like to know if this saturation is normal or if I am configuring something wrong?

 

 

 

> I would like to know if this saturation is normal or if I am configuring something wrong?

"normal" depends on what all you've got going on with the other interrupts and DMA operations.  The two OCTOSPI ports, LTDC and USB HS ports are all potentially high bandwidth interfaces.  I have no experience with OCTOSPI or LTDC, so I don't know what kind of load they (or their HAL drivers) put on the CPU.  FLASH and external memory wait states also impact CPU throughput, as does all the arbitration between all the different peripherals and the memory bus.

But in general, any time you are trying to handle incoming or outgoing data at a "high" data rate, DMA should be your first choice as it minimizes the number of CPU cycles needed to send/receive the data.  And for something like your SPI interface with a 4.2MHz clock can potentially  receive around 500K bytes/second. That definitely fits the "high data rate" that should use DMA.

Hello @fernandogamax 

 

It seems like you have found a solution to your problem.
If it is the case, could you select the answer giving the solution (maybe your last comment) as solution.
That would help people with the same issue as you to quickly get an answer!

 

Regards,

Gaetan Godart
Software engineer at ST (TouchGFX)