Hi,
I am using NXP mkv30f64vlf10 for BLDC controller application. I used FTM module dual edge capture feature to capture the rising and falling edge of HALL sensor A (which is connected to FTM1 channel 0).
Interrupts trigger for rise and fall in sensor once the motor rotates , but sometimes at motor start the program gets stuck inside the Hall interrupt loop.
there are two if else conditions one for rising edge and one for falling edge , initially the logic got stuck inside the rising edge loop and never enters falling edge else if. So, I cleared the flag status for rising edge , then the loop exits and enters falling edge but never comes back to the rising edge in the next cycle.
I am sharing the interrupt logic, if someone can take a look and offer a solution or any suggestion would be really helpful.
M1_HALL_TIMER is FTM1
static void InitHall(void)
{
ftm_config_t hall_ftm_info;
ftm_dual_edge_capture_param_t edge_param;
FTM_GetDefaultConfig(&hall_ftm_info);
// Set prescalar value
hall_ftm_info.prescale = kFTM_Prescale_Divide_64;
/* Initialize FTM module */
FTM_Init(M1_HALL_TIMER, &hall_ftm_info);
edge_param.mode = kFTM_Continuous;
/* Set capture edges to calculate the pulse width of input signal */
edge_param.currChanEdgeMode = kFTM_RisingEdge;
edge_param.nextChanEdgeMode = kFTM_FallingEdge;
/* Setup dual-edge capture on a FTM channel pair */
// Filter Enabled - 4
FTM_SetupDualEdgeCapture(M1_HALL_TIMER, M1_HALL_TIMER_INPUT_CAPTURE_CHANNEL_PAIR, &edge_param, 100);
/* Set the timer to be in free-running mode */
FTM_SetTimerPeriod(M1_HALL_TIMER, 0xFFFF);
/* Enable first channel interrupt */
FTM_EnableInterrupts(M1_HALL_TIMER, M1_HALL_TIMER_FIRST_CHANNEL_INTERRUPT_ENABLE);
/* Enable second channel interrupt when the second edge is detected */
FTM_EnableInterrupts(M1_HALL_TIMER, M1_HALL_TIMER_SECOND_CHANNEL_INTERRUPT_ENABLE);
/* Enable overflow interrupt */
FTM_EnableInterrupts(M1_HALL_TIMER, kFTM_TimeOverflowInterruptEnable);
/* Enable at the NVIC */
EnableIRQ(M1_HALL_IRQN);
NVIC_SetPriority(M1_HALL_IRQN, 3);
FTM_ClearStatusFlags(M1_HALL_TIMER, M1_HALL_TIMER_FIRST_CHANNEL_FLAG);
FTM_ClearStatusFlags(M1_HALL_TIMER, M1_HALL_TIMER_SECOND_CHANNEL_FLAG);
FTM_StartTimer(M1_HALL_TIMER, kFTM_SystemClock);
}
void M1_HALL_IRQ_HANDLER(void){
static uint32_t g_timerOverflowInterruptCount = 0U;
static uint32_t g_hallfirstChannelOverflowCount = 0U;
if ((FTM_GetStatusFlags(M1_HALL_TIMER) & kFTM_TimeOverflowFlag) == kFTM_TimeOverflowFlag)
{
/* Clear overflow interrupt flag.*/
FTM_ClearStatusFlags(M1_HALL_TIMER, kFTM_TimeOverflowFlag);
g_timerOverflowInterruptCount++;
}
else if ((FTM_GetStatusFlags(M1_HALL_TIMER) & M1_HALL_TIMER_FIRST_CHANNEL_FLAG) == M1_HALL_TIMER_FIRST_CHANNEL_FLAG &&
!((FTM_GetStatusFlags(M1_HALL_TIMER) & M1_HALL_TIMER_SECOND_CHANNEL_FLAG) == M1_HALL_TIMER_SECOND_CHANNEL_FLAG))
{
// Rising Edge
g_sM1HallSensor.raising_edge_detected = true;
g_hallfirstChannelOverflowCount = g_timerOverflowInterruptCount;
FTM_DisableInterrupts(M1_HALL_TIMER, M1_HALL_TIMER_FIRST_CHANNEL_INTERRUPT_ENABLE);
}
else if ((FTM_GetStatusFlags(M1_HALL_TIMER) & M1_HALL_TIMER_SECOND_CHANNEL_FLAG) == M1_HALL_TIMER_SECOND_CHANNEL_FLAG)
{
// Falling Edge
g_sM1HallSensor.falling_edge_detected = true;
/* Clear second channel interrupt flag.*/
FTM_ClearStatusFlags(M1_HALL_TIMER, M1_HALL_TIMER_FIRST_CHANNEL_FLAG);
FTM_ClearStatusFlags(M1_HALL_TIMER, M1_HALL_TIMER_SECOND_CHANNEL_FLAG);
uint32_t raising_edge = M1_HALL_TIMER->CONTROLS[0].CnV;
uint32_t falling_edge = M1_HALL_TIMER->CONTROLS[1].CnV;
// 65536 = FTM1->MOD
g_sM1HallSensor.pulse_width = (g_timerOverflowInterruptCount - g_hallfirstChannelOverflowCount) * 65536U
+ (falling_edge - raising_edge) + 1U;
// Reset counters
g_timerOverflowInterruptCount = 0;
g_hallfirstChannelOverflowCount = 0;
FTM_DisableInterrupts(M1_HALL_TIMER, M1_HALL_TIMER_SECOND_CHANNEL_INTERRUPT_ENABLE);
}
else
{
__asm volatile ("nop");
}
// If no update in 0.5 seconds (MOD/ (40MHz/64)) * 5 set pluse diff to zero
if (g_timerOverflowInterruptCount > 5){
g_sM1HallSensor.pulse_width = 0U;
// Reset counters
g_timerOverflowInterruptCount = 0;
g_hallfirstChannelOverflowCount = 0;
}
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F
Store immediate overlapping exception return operation might vector to incorrect interrupt. */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}
thanks and regards,
Goutham