I'm trying to copy my input trigger mask before start reading it and setting the outputs, but I suspect that maybe the input interrupt sometimes happens between these two lines below so I missing out the last change, because when changing the input fast, sometimes the output stays on its previous state.
trigger_mask_t tmask = gpio_trigger_mask;
gpio_trigger_mask.bits = 0;
if (!tmask.bits)
// reading the inputs and setting the outputs here.
My interrupt function:
void gpioCbFxn(PIN_Handle handle, PIN_Id pinId)
{
for (uint8_t i = 0; i < sizeof(GPIO_tab); i++)
{
if (pinId == GPIO_tab[i])
{
gpio_trigger_mask.bits |= (1 << i);
return;
}
}
}
My trigger mask struct:
typedef struct {
uint16_t IN1 : 1,
IN2 : 1,
IN3 : 1,
...;
} trigger_mask_fields_t;
typedef union {
trigger_mask_fields_t fields;
uint16_t bits;
} trigger_mask_t;
Currently I have no debugger for that chip.
Is that theory possible? if so, how can I solve it?
You need to disable the interrupt before you read from the mask variable, and after clearing the mask, you will enable the interrupt again. You make this little block kind of "atomic" from the view of the interrupt.
This way an interrupt, which would be served during both statements, will be pending until the enable, and it will be served then. No interrupts are lost.
This is a very similar situation as if the interrupt occurs during the first or during the second statement. Often such a statement is compiled into multiple assembly instructions, and the interrupt can be served "in the middle" of the statement.
Such a delayed interrupt is very similar to an interrupt that is served right after the second statement.