Hello
I'm using a K60 on KDS3.2.0 with MQX 4.2.
To drive stepper motor, I use the Kernel ISR to instead of MQX ISR to have less latency as possible.
This work fine, but I have a strange behavior which lead me to ask some question.
First, this is my simplified code:
uint16_t DV_Stepper_iFifoLevel[8];
uint16_t DV_Stepper_iAllFifoLevelSum;
...
void MyInitFunction(void)
{
...
_int_install_kernel_isr(INT_FTM0, DV_Stepper_iFTM0IRQ);
_bsp_int_init(INT_FTM0, 1, 0, TRUE);
_int_install_kernel_isr(INT_FTM3, DV_Stepper_iFTM3IRQ);
_bsp_int_init(INT_FTM3, 1, 0, TRUE);
}
void MainTask(void)
{
....
DV_Stepper_iFifoLevel[MotorID]++;
DV_Stepper_iAllFifoLevelSum++;
....
}
/* Interrupt function ..... */
static void DV_Stepper_iFTM0IRQ(void)
{
DV_Stepper_iFTMxIRQ(0);
}
static void DV_Stepper_iFTM3IRQ(void)
{
DV_Stepper_iFTMxIRQ(3);
}
static inline void DV_Stepper_iFTMxIRQ(uint8_t FTMIndex)
{
/* Chn+1 Interrupt */
if ((DV_Stepper_FTMx_Cn1SC(FTMIndex, 0) & FTM_CnSC_CHF_MASK) != 0)
{
DV_Stepper_iMotorStepControl(FTMIndex, 0);
DV_Stepper_FTMx_Cn1SC(FTMIndex, 0) &= ~FTM_CnSC_CHF_MASK; /* clear flag */
}
/* Chn+1 Interrupt */
if ((DV_Stepper_FTMx_Cn1SC(FTMIndex, 1) & FTM_CnSC_CHF_MASK) != 0)
{
DV_Stepper_iMotorStepControl(FTMIndex, 1);
DV_Stepper_FTMx_Cn1SC(FTMIndex, 1) &= ~FTM_CnSC_CHF_MASK; /* clear flag */
}
/* Chn+1 Interrupt */
if ((DV_Stepper_FTMx_Cn1SC(FTMIndex, 2) & FTM_CnSC_CHF_MASK) != 0)
{
DV_Stepper_iMotorStepControl(FTMIndex, 2);
DV_Stepper_FTMx_Cn1SC(FTMIndex, 2) &= ~FTM_CnSC_CHF_MASK; /* clear flag */
}
/* Chn+1 Interrupt */
if ((DV_Stepper_FTMx_Cn1SC(FTMIndex, 3) & FTM_CnSC_CHF_MASK) != 0)
{
DV_Stepper_iMotorStepControl(FTMIndex, 3);
DV_Stepper_FTMx_Cn1SC(FTMIndex, 3) &= ~FTM_CnSC_CHF_MASK; /* clear flag */
}
}
static inline void DV_Stepper_iMotorStepControl(const uint8_t FTMIndex, const uint8_t ChannelPairIndex)
{
const MotorAssocation[2][4] =
{
/* FTM 0 */
{0, 1, 2, 3},
/* FTM 3 */
{4, 5, 6, 7}
};
const uint8_t MotorID = MotorAssocation[FTMIndex][ChannelPairIndex];
.....
DV_Stepper_iFifoLevel[MotorID]--;
DV_Stepper_iAllFifoLevelSum--;
......
}
Like you can see, I have a table of counter DV_Stepper_iFifoLevel[8] and a global sum counter DV_Stepper_iAllFifoLevelSum.
Therorically, DV_Stepper_iFifoLevel[0] + DV_Stepper_iFifoLevel[1]+... DV_Stepper_iFifoLevel[7] is always equal to the DV_Stepper_iAllFifoLevelSum.
But sometime, at the end of my behavior, the sum is equal to 1 2 or 4 like each Fifo independant counter DV_Stepper_iFifoLevel[n] arr all to 0!
I can't explain this!.
-> Is a Kernel ISR can be interrupted itself?
-> do you see some case which could be explain this?
Thank
Solved! Go to Solution.
In fact, if Main_Task is interrupted between counter increment, this nos cause problem.
But if interrupt occurs during increment (which take many assembler instruction) this cause problem.
So I disabled FTM interrupt before increment both counter, this resolve my problem.
In fact, if Main_Task is interrupted between counter increment, this nos cause problem.
But if interrupt occurs during increment (which take many assembler instruction) this cause problem.
So I disabled FTM interrupt before increment both counter, this resolve my problem.
Thanks for sharing