cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H745 discovery evk Missed External Interrupt in FreeRTOS

HPate.10
Associate III

Hello,

I’ve just started using FreeRTOS with an ARM Cortex m7 core. I’m using a sensor that provides an interrupt at every 62.5uS. based on that interrupt I have to read the 27-byte sensor data over SPI for that I have created one task(Read sensor data task) as below.

My issue is, that my task is not synchronized with the interrupt. That means whenever the first interrupt occurs the task runs to read sensor data using SPI and parsed the data, before completion of reading and parsing data the other interrupts occur.

As per the sensor datasheet: DOUT is latched out at the SCLK rising edge. DRDY is pulled high at the SCLK falling edge. Note that DRDY goes high on the first SCLK falling edge, regardless of whether data are being retrieved from the device or command is being sent through the DIN pin.

DRDY is the interrupt that active low. here I have attached the datasheet snap.

0693W00000StfFYQAZ.pngI have configured coreM7 CPU clock 400Mhz. And code optimization level is 0.

0693W00000Stf8hQAB.png 

So I want to know what is the time required to run one instruction on CoreM7 CPU.

Also, I want to know the time of context switching from ISR to task wakeup. (I am using vTaskNotifyGiveFromISR())

Could you please help me to find out the best approach to achieve read data without losing interrupt and task synchronization?

I have used HAL API to configure interrupt and ISR.

I am using SPI with DMA HAL API to read sensor data.

Below I have attached the pseudo-code of my task and ISR.

ISR

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

 switch(GPIO_Pin)

 {

   case SPI1_INT_Pin: /* drdy interrupt handling for */

   /* When device is in normal conversion mode */

       drdy_interrupt_count++; /* Interrupt count for receive all data */

vTaskNotifyGiveFromISR()

     break;

   default:

     break;

 }

}

Sensor data read task

void Task(void *argument)

{

 /* Infinite loop */

 for(;;)

 {

   xTaskNotifyWait()

   {

      parsed_count++;

      low_level_send_rdata_cmd(); /*Send RDATA command to receive 28 bytes from */

parse_data(); /*Parsed raw data and convert into mVolt */

printf('parsed data');

   }

 }

}

3 REPLIES 3

I don't know, do it quicker?

Initiate the transfer in the callback, and process it from the SPI completion?

Clock the SPI faster

Find some way to automate with a CPLD

Consider decimation, such that you fetch multiples, rather than this complex choreography for each and every one singularly

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
HPate.10
Associate III

Hi @Community member​,

Thank you for your response!

=============================================================

"Initiate the transfer in the callback, and process it from the SPI completion?"

What i understad, your trining to say use "low_level_send_rdata_cmd();" function in ISR callback.

But unfortunately, it's not possible because I am using the "HAL_SPI_Receive_DMA()" API inside the above function. "HAL_SPI_Receive_DMA()" API has its own interrupt. if use this inside the HAL_GPIO_EXTI_Callback() then there would become a nested interrupt of NVIC.

=============================================================

"Clock the SPI faster"

SPI clock speed is 12.5Mhz

=============================================================

"Find some way to automate with a CPLD"

If you share some documents or links to CPLD then it would be great for me.

Piranha
Chief II

Processing and sending on SPI could be a problem, but calling a printf() at a 16 kHz rate most likely is the worst. Especially if it prints on an UART or some other slow interface.