I've been using my Giga pretty intensively for a year or so now and have noticed that the performance seemed to be lower than it really should be. Recently, while debugging it I put in a 50kHz wave on an input pin and just had an infinite loop match it on an output pin, all on the M4 core.
What I found was that 50% of the time I was getting <1us delay between the input changing and the output matching it. The other 50% of the time it was completely unresponsive. This is happening on a 1ms on, 1ms off cycle.
This set off huge alarm bells for me as my system needs better responsiveness than that. Digging through I found that the culprit is the interrupt for LP_TIM5, Low Power Timer 5. If I disable this right before running my matching function everything runs perfectly. Putting the disable into my setup() function for the M4, however, prevents the M4 from running at all.
So, anybody have any idea what's going on here? I absolutely cannot tolerate a 1ms dead spot on a 50% duty cycle, but what is this doing and should I be concerned leaving it off most of the time?
I'm disabling the interrupt as so:
NVIC_DisableIRQ(LPTIM5_IRQn ); /*!< LP TIM5 global interrupt */
As for the code, it's quite long, but the debug routine I was using to demonstrate the issue was this:
if (sub_algo == 0xFF){
uint8_t i=1;
int val;
while(i==1){
val = read_pin(EXT1); // Get the value from input pin
set_pin(MIR1, val); // Mirror that back out to an output pin
}
}
M7 uses TIM5 for the us_ticker but M4 uses TIM2. Only thing I can think of using TIM5 on M4 is PWM_5 - are you using pin D5 for anything?
I would try disabling low-powers tickers and see if the problem persists. Changing line 34 of wiring.cpp to #if DEVICE_LPTICKER_NO will force regular tickers.
Also, what is set_pin using? Arduino API, mbed API or direct reg updates?
curious if you guys came up with a a way to disable the us_ticker code. i don't need it and want/need access to TIM2 and TIM5 for my own purposes. when i simply try to override and configure TIM5 for my self everything works from a counting POV but i can't enable the interrupt with out the whole thing hanging. something is blocking this and this leads to a fail when it finally tries to overflow
here is my code on TIM5 for the M7 core. this code hangs because of a problem enabling the interrupt. if i disable that and have it count to a higher number and display CNT periodically via the main loop then i can see it counting correctly at the correct rate. but i can't enable the interrupt for some reason which i believe is related to the us_ticker code
void setupTIM5() {
RCC->APB1LENR |= RCC_APB1LENR_TIM5EN; // Enable TIM5 clock
TIM5->CR1 = 0; // Reset control register
TIM5->PSC = 4; // Prescaler set to 5 (PSC + 1)
TIM5->ARR = 0xFFFFFFFF; // Max auto-reload value (free-running)
TIM5->CNT = 0; // Reset counter
TIM5->DIER |= TIM_DIER_UIE; // Enable update interrupt
// Configure PA4 as Alternate Function (AF2 for TIM5_ETR)
GPIOA->MODER &= ~(0b11 << (4 * 2)); // Clear mode bits for PA4
GPIOA->MODER |= (0b10 << (4 * 2)); // Set to Alternate Function mode
GPIOA->AFR[0] &= ~(0xF << (4 * 4)); // Clear AF selection for PA4
GPIOA->AFR[0] |= (0x2 << (4 * 4)); // Set AF2 (TIM5_ETR)
// Configure TIM5 to use external clock mode 1 on ETR (PA4)
TIM5->SMCR = (7 << TIM_SMCR_SMS_Pos) | // External Clock Mode 1
(7 << TIM_SMCR_TS_Pos) | // Trigger source = ETR (PA4)
(1 << 12); // Set ETR prescaler to divide by 2
// Ensure ETR is active high
TIM5->SMCR &= ~(1 << 15); // Clear ETP bit to select active high
TIM5->ARR = 999999; // Set rollover to 1,000,000 counts
TIM5->CR1 |= TIM_CR1_ARPE;
//TIM5->EGR = TIM_EGR_UG; // Manually trigger an update event
TIM5->CR1 |= TIM_CR1_CEN; // Enable the counter
NVIC_EnableIRQ(TIM5_IRQn); // Enable TIM5 interrupt in NVIC
}
extern "C" void TIM5_IRQHandler(void) {
if (TIM5->SR & TIM_SR_UIF) {
TIM5->SR &= ~TIM_SR_UIF;
secondsCounter++;
topSec = 1;
}
}