I configure MR0 = CLOCK*500-1 and MR3 = CLOCK*1000-1 [CLOCK is the cpu frequency in MHz, which in my case is 100]. PR=0. Thus, MR0 corresponds to 0.5ms and MR3 to 1ms, that is the time until match.
I then configure MCR to interrupt on MR0 and to reset counter on MR3.
I should get an interrupt periodically every 0.5ms because of MR0, BUT I get interrupt every 1 ms [precisely; I can vary MR0 and MR3 values, but interrupt always happens on the period according to the MR3 value]. What might be explanation of such behavior?
Hi Vytautas C.
At first, you must make sure your Timer frequency is correct.
Do you test the official lpcopen code for LPC1769, which you can find it from this link:
LPCOpen Software for LPC17XX|NXP
SystemCoreClockUpdate();
Board_Init();
/* Enable timer 1 clock */
Chip_TIMER_Init(LPC_TIMER0);
/* Timer rate is system clock rate */
timerFreq = Chip_Clock_GetSystemClockRate();
/* Timer setup for match and interrupt at TICKRATE_HZ */
Chip_TIMER_Reset(LPC_TIMER0);
Chip_TIMER_MatchEnableInt(LPC_TIMER0, 1);
Chip_TIMER_SetMatch(LPC_TIMER0, 1, (timerFreq / TICKRATE_HZ1));
Chip_TIMER_ResetOnMatchEnable(LPC_TIMER0, 1);
Chip_TIMER_Enable(LPC_TIMER0);
/* Enable timer interrupt */
NVIC_ClearPendingIRQ(TIMER0_IRQn);
NVIC_EnableIRQ(TIMER0_IRQn);
The match value is timerFreq / TICKRATE_HZ1. timerFreq = Chip_Clock_GetSystemClockRate();
Please check the lpcopen code on your side again.
If you still have question about it, please kindly let me know!
Have a great day,
Kerry
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Timer clock frequency is definitely correct. I think sufficient evidence for that is that I get interrupt on whatever period I like by writing appropriate value to MR3, e.g. I assign MR3=CLOCK*4567-1 and get interrupt every 4567us precisely, but I want to get interrupt on match with MR0, which I assign a smaller value, e.g. MR0=CLOCK*2500-1, and I configure MCR accordingly, i.e. MCR = (1<<0) | (1<<10).
I might give my all timer initialization routine [I do not use lpcopen]:
void Timer0_Init(void) {
PCONP |= (1<<1);
PCLKSEL0 = (PCLKSEL0&(~(3<<2))) | (1<<2); //pclk=cclk
T0TCR = 2; //counters disabled and reset
T0CTCR = 0; //timer mode
T0PR = 0;
T0MR0 = CLOCK*500-1;
T0MR3 = CLOCK*1000-1;
T0MCR = (1<<0) | (1<<10); //interrupt on MR0, reset on MR3
IPR0 = (IPR0&(~(0x1f<<11))) | (1<<11); //interrupt priority
ISER0 = (1<<1); //interrupt enable
T0TCR = 1; //counters enabled
}
A few notes also:
- I tried to change Timer0 to Timer1 and get the same results;
- T0IR indicates that the interrupt source is MR0, although interrupt happens on the period according to MR3.
I have a hypothesis that interrupt is asserted only when T0TC is reset to zero and I might think of a few tests that would confirm that, but I'm not sure I will do them, because I achieved my goal with other means than with such a usage of Timer as I described and I have to move forward. I wrote here with the expectation that this is a universal error and that someone would duplicate it and get the same result.