Hello DevZone,
For my project I have a number of pins generating interrupts from different sensors.
I've read that GPIOTE IN events consume a bit more current than the port event, so I opted to use the port event in my project.
I configure each interrupt pin to have high or low sensing depending on the logic level of that interrupt.
In my GPIOTE port event I handle the interrupt like this:
if (NRF_GPIOTE->EVENTS_PORT != 0)
{
// Clear the event to allow it to trigger again.
NRF_GPIOTE->EVENTS_PORT = 0;
// Loop through all pins available on port 0.
for (uint8_t i = 0; i < 32; i++)
{
// Check if there is a bit set in the latch register.
if (NRF_P0->LATCH & 1 << i)
// Clear the latch by writing a one to it.
NRF_P0->LATCH |= 1 << i;
// Switch statement for calling functions that have been generating the interrupt.
switch (i)
{
case GYRO_INTERRUPT:
p_stMask->GyroInterrupt = true;
break;
case MAG_INTERRUPT:
p_stMask->MagnetoInterrupt = true;
break;
case TEMP_INTERRUPT:
p_stMask->TemperatureInterrupt = true;
break;
default:
break
}
}
}
}
In my main loop I process all pending interrupts because I do not want my interrupt routine to be very long.
The problem I am facing at this moment is that when I use a single sensor everything works fine but as soon as I use multiple sensors I start missing interrupts.
What I could see is that if the processor is in my GPIOTE loop and another pins senses a new change it doesn't process this.
Example:
All sensors run at their native sampling speed and the temperature sensor is the first to assert its interrupt pin.
The microcontroller senses this and calls the GPIOTE interrupt handler.
Whilst the microcontroller is processing the interrupt, the gyroscope asserts its interrupt pin.
The microcontroller does sense this, writes it to the latch register but doesn't process it.
I even tried to have the GPIOTE handler as short as possible by reading the latch register into a variable and then clear itself and ending the handler there.
This still causes some interrupts to not trigger.
// Check if the port event has triggered.
if (NRF_GPIOTE->EVENTS_PORT != 0)
{
// Clear the event to allow it to trigger again.
NRF_GPIOTE->EVENTS_PORT = 0;
// Logical OR the latch into a temporary variable.
temp |= NRF_P0->LATCH;
//Clear the latch.
NRF_P0->LATCH = 0xFFFFFFFF;
}
Does anyone have an idea how I could tackle this problem?
I cannot use all GPIOTE IN events as I have more interrupt sources than available GPIOTE channels.