The HAL gpio_irq_api stores object IDs, which serve as a form of context
for the dispatch of the interrupt handler in the drivers level
InterruptIn Class. The way this is achieved is that the InterruptIn
Class casts its address to uint32_t, which is stored as the ID.
This results in compilation failure when the size of an object pointer
is greater than uint32_t, for example when building on a PC for unit
testing.
In order to allow Unit Testing of the InterruptIn Class, we replace the
use of uint32_t with uintptr_t (type capable of holding a pointer),
which allows portability and expresses intentions more clearly.
In aid of this latter goal, we also replace the use of the name "id"
with "context", to improve clarity - these are addresses of the context
related to that callback.
The multiple InterruptIn object with same pin_index sharing same IRQ line.
So the second object will overwrite the first one. To catch this as error,
implemented an error catching functionality.
critical section added in gpio_irq init and free functions
to protect shared code structures
Note that other functions are protected in API level in InterruptIn
In case we've run through the entire GPIOs loop, withouth finding a
matching interrupt, we're in the case of a spurious interrupt, let's
raise an error to track it down.
When disabling GPIO irq, also the falling / rising edge settings need
to be reset (EXTI_RTSR and EXTI_FTSR registers).
If not reset, the same EXTI line can be later enabled again with a wrong
Rising / Falling configuration. This was especially seen and reported in
ci-test tests-api-interruptin on NUCLEO_F446RE target where DIO2=PA_10 and
DIO6=PB_10 were successively tested: as they are sharing the same EXTI_LINE
(EXTI_10), this resulted in calling the irq_handler with wrong
IRQ_FALL/IRQ_RAISE parameter and donothing being called in loop.
Instead of using HAL_GPIO_Init / Deinit which makes a lot of registers
being written and re-written, and which creates extra gpio / pin / irq
dependencies, we directly set the IRQ related registers thanks for the
STM32 LL layers which provides APIs to modify registers.