I’ve been following this thread because I’m also working on a real-time project using the Photon.
I’ve measured the interrupt latency and got the same approximately 1.8us overhead. I can live with that if it were consistent, but it’s not, of course, because other higher priority interrupt routines can be running.
So, a solution might be to raise the interrupt priority of the line I need. The standard API doesn’t provide a way to do this, so (with a fair amount of trepidation) I’ve been looking under the hood, starting with the hints @Ric and @ScruffR offered. And I’ve got an approach which seems it might work … IF all the guesses I’ve made are correct.
Before going into the details: is this doable? Will it work? Is there a better way? I’m new to the Photon, so I’ve had to make a lot of guesses and I’m not very confident that this is even close to right. Review and advice from someone who knows this stuff would be appreciated.
Details:
I want to make the interrupt priority on pin D0, say, very high (which I assume means 0 (zero)). (My interrupt service routine isonly 4 or 5 lines, so I think this is safe.)
I think the way to do this is to make a call to NVIC_Init()
with a filled in NVIC_InitTypeDef
structure. To fill in that structure properly, we have to go from the D0 pin to a “pin source” to an IRQ channel. Here’s the bare bones of the code:
int pin = D0;
uint8_t GPIO_PinSource = PIN_MAP[pin].gpio_pin_source;
NVIC_InitStructure.NVIC_IRQChannel = GPIO_IRQn[GPIO_PinSource];
Whoops, PIN_MAP
needs to be filled in first, so doing that comes before the above lines. Here’s the code for that (which I found in “hal_src/core/pinmap_hal.c”):
STM32_Pin_Info* PIN_MAP;
PIN_MAP = HAL_Pin_Map();
For the GPIO_IRQn[]
array above, I had to cheat because it doesn’t appear to be included in any of the headers that “applications.h” includes and I couldn’t find a way to get a pointer to it the way HAL_Pin_Map()
provides a pointer to the PIN_MAP[]
array. So I just copied it from “hal/src/core/interrupts_hal.c”. (Yeah, yeah, I know, this is very bad practice, akin to using “proto-matter”, but … Is there something better?)
Then there’s this code from “firmware/bootloader/src/photon/stdperiphdriver/misc.c”.:
if(GPIO_PinSource > 4)
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 14;
else
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 13;
which I would modify with a priority of, say, zero. (FWIW, the definition of NVIC_InitTypeDef can be found in
“firmware/hal/src/photon/wiced/platform/MCU/STM32F2xx/peripherals/libraries/inc/misc.h”.)
Then all that’s left is the call to NVIC_Init().
NVIC_Init(&NVIC_InitStructure);
So, again, is there anyone with experience with this level of code who can advise? Thanks!