How to clear Timer0 match IT?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to clear Timer0 match IT?

2,410 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Bela on Thu Jul 09 11:26:11 MST 2015
Ladies and gentlemen,

I need assistance again.

I wrote a silly little code for my LPCXpresso board. It is connected to a base board, and I try to control the brightness of the RGB LED by PWM.
I' like to use Timer0 to generate the PWM signal, using Match0 - Match3 registers.
My plan is to independently control the 3 LEDs, but at the moment I control them all together.
Match1 determines the PWM period, when I got a Match1 IT, I turn all LEDs on.
Match0, Match2, Match3 registers are to determine the duty cycle, the corresponding IT routines turn the LEDs off.

If I write the Timer0_IT routine the following way, then it works:

void TIMER0_IRQHandler (void)
{
NVIC_ClearPendingIRQ(TIMER0_IRQn);
if (( LPC_TIMER0->IR & 1<<0) == 1)  // if Timer0 Match0 resulted an IT
{
LPC_TIMER0->IR |= (1<<0);             // clear Match0 IT request
Timer0Match0IT ();                           // then call Timer0Match0IT
}
else
{ Timer0Match1IT () ;};                     // call Timer0Match1IT
        return ;
}

So, this code works, but if I single step through it (LPCXpresso 7.8.0), neither the Match0 nor the Match1 IT request bits are cleared. I see peripherals->Timer0->IR->MR0I and MR1I bits.

Since my plan is to use all the 4 match registers, I modified my code:

void TIMER0_IRQHandler (void)
{
NVIC_ClearPendingIRQ(TIMER0_IRQn);
if (( LPC_TIMER0->IR & 1<<0) == 1)// if Timer0 Match0 resulted an IT
{
LPC_TIMER0->IR |= (1<<0);// clear IT request
Timer0Match0IT ();// then call Timer0Match0IT
};
if (( LPC_TIMER0->IR & 1<<1) == 1)// if Timer0 Match1 resulted an IT
{
LPC_TIMER0->IR |= (1<<1);// clear IT request
Timer0Match1IT ();// then call Timer0Match1IT service routine
};
       return ;
}

When I debug this code, Timer0Match0IT is called periodically, but Timer0Match1IT never called, despite I see the corresponding IT request bit is set.

What is the reason, the second if condition doesn't get true?
What is the proper way to delete the Timer0Match0 interrupt? (Yes, I read in the manual: I have to write a 1 into the corresponding register. But it doesn't clear the bit.)

Here's the routine that sets Timer0 up at the begin of the program:

void Timer0Setup (void)// Timer0 creates the PWM signal to control the brightness of the LED.
{LPC_SYSCTL->PCONP|= 1<<1;// Power up Timer0
LPC_SYSCTL->PCLKSEL[0] = (LPC_SYSCTL->PCLKSEL[0] & ~(1<<2 | 1<<3)) | (1<<2 | 0<<3);
LPC_TIMER0->MCR = 0;// clear all bits in Match Control Register
LPC_TIMER0->CCR= 0;// clear all bits in Capture Control Register
LPC_TIMER0->CTCR= 0;// Clear all bits in Count Control Register
LPC_TIMER0->TCR = 0;// clear all bits in Timer Control Register
LPC_TIMER0->EMR= 0;// clear all bits in Timer External Match Register
LPC_TIMER0->PR = 12;// Prescale register = 12
LPC_TIMER0->MCR= (LPC_TIMER0->MCR & ~0x7ff) | (1<<0 | 0<<1 | 1<<3 | 1<<4 ); //| 1<<6 | 1<<9);// Match control register IT enabled
LPC_TIMER0->MR[0]  = 503;// initial value for Match0 register (Duty cycle Red LEDs) at 26°(145. Value Up)
LPC_TIMER0->MR[1]  = 10100;// initial value for Match1 register (PWM Period)
LPC_TIMER0->MR[2] = 9153;// initial value for Match2 register (Duty Cycle Green Led) at 146° (812. value UP)
LPC_TIMER0->MR[3]= 5345 ;// initial value for Match3 register (Duty cycle Blue Led at 266°   (1479. value Down)
LPC_TIMER0->TCR= 1<<0;// Timer control register. Timer0 enabled
return ;
}
0 Kudos
Reply
14 Replies

2,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Fri Jul 10 08:51:49 MST 2015
An easy way to check IR is to set the breakpoint in a stop / start sequence:

void TIMER0_IRQHandler (void)
{
 NVIC_ClearPendingIRQ(TIMER0_IRQn);
 if(LPC_TIMER0->IR & (1<<0))// if Timer0 Match0 resulted an IT
 {
  LPC_TIMER0->TCR&= ~(1<<0);// stop timer
[color=#f00](insert breakpoint here)[/color]  LPC_TIMER0->IR = (1<<0);// clear IT request
  LPC_TIMER0->TCR|= (1<<0);// start timer
  Timer0Match0IT();// then call Timer0Match0IT
 }
 if(LPC_TIMER0->IR & (1<<1))// if Timer0 Match1 resulted an IT
 {
  LPC_TIMER0->TCR&= ~(1<<0);// stop timer
[color=#f00](insert breakpoint here)[/color]  LPC_TIMER0->IR = (1<<1);// clear IT request
  LPC_TIMER0->TCR|= (1<<0);// start timer
  Timer0Match1IT();// then call Timer0Match1IT service routine
 }
}
0 Kudos
Reply

2,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Bela on Fri Jul 10 08:15:13 MST 2015

Quote:
Clearing bit 0 of TCR is stopping the timer



Well, it is right, but it doesn't help in single stepping. I thought there's a method to stop the peripheral clock when single step or when a breakpoint is reached.

Back to the origin:
If I break the code by a breakpoint in the IT service routine, then I single step to detect what's wrong, I can step back to the main() routine.

Since the peripheral clock continously runs, I do not recognize the cleared IT flag, because it is set back so quickly I cannot see.

Am I right until this?

Then, when I single step back to the main() loop, why I don't get the next IT immediately? I am able to single step there for a very long time in the while (1) loop.

It would be consequent to have the next IT immediately, since the corresponding IT flag is set.
0 Kudos
Reply

2,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Fri Jul 10 07:07:19 MST 2015

Quote: Bela
...how to stop the timer.



Clearing bit 0 of TCR is stopping the timer 



Quote: Bela
Where can I read more about these possibilities? Excuse me, I don't clearly understand what EMR is...



UM10360:


Quote:
21.5 Pin description
...
Output External Match Output - When a match register (MR3:0) equals the timer counter (TC) this output can either toggle, go low, go high, or do nothing. The External Match Register (EMR) controls the functionality of this output. Match Output functionality can be selected on a number of pins in parallel. So you can use EMR to switch MAT pins, if they are selected.


In your case:

void EMR_init(void)
{
 LPC_IOCON->PINSEL[3] |= (3<<24) | (3<<26);//select MAT0.0 (P1[28]) / MAT0.1 (P1[29])
 LPC_TIMER0->EMR = (3<<4)|(3<<6); //set match function 1:clear 2:set 3:toggle
}


Now MAT0.0 / MAT0.1 pins are toggled 

Of course you can also switch this pins with setting / clearing EM bit:


Quote:
EM0 External Match 0.
When a match occurs between the TC and MR0, this bit can either toggle, go low, go high, or do nothing, depending on bits 5:4 of this register. This bit can be driven onto a MATn.0 pin, in a positive-logic manner (0 = low, 1 = high).


In your case:

LPC_TIMER0->EMR |= (1<<0);//set MAT0.0

0 Kudos
Reply

2,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Bela on Fri Jul 10 06:45:49 MST 2015

Quote: R2D2


You don't stop the timer with a breakpoint, so it's still running while you are debugging  :O



Oooh, thanks, than it was my mistake.
I thought if the CPU is stopped due to single stepping, it is obvious to stop the peripherals as well. So, it isn't. OK, I have to memorize it :-)


Quote: R2D2

If you enable EMR you can see how Match outputs are switched while you are stepping through the program  ;-)

If you stop the timer you can see how IR bits are cleared  :)



Where can I read more about these possibilities? Excuse me, I don't clearly understand what EMR is and how to stop the timer.
0 Kudos
Reply

2,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Bela on Fri Jul 10 06:45:47 MST 2015

Quote: R2D2


You don't stop the timer with a breakpoint, so it's still running while you are debugging  :O



Oooh, thanks, than it was my mistake.
I thought if the CPU is stopped due to single stepping, it is obvious to stop the peripherals as well. So, it isn't. OK, I have to memorize it :-)


Quote: R2D2

If you enable EMR you can see how Match outputs are switched while you are stepping through the program  ;-)

If you stop the timer you can see how IR bits are cleared  :)



Where can I read more about these possibilities? Excuse me, I don't clearly understand what EMR is and how to stop the timer.
0 Kudos
Reply

2,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Fri Jul 10 06:25:25 MST 2015

Quote: Bela
The program works, therefore this IT bit is probably cleared. But look at the screenshot please: TIMER0->IR->MR0I bit remained 1.

Shouldn't it show me 0?



Yes and No  :~

You don't stop the timer with a breakpoint, so it's still running while you are debugging  :O

If you enable EMR you can see how Match outputs are switched while you are stepping through the program  ;-)

If you stop the timer you can see how IR bits are cleared  :)
0 Kudos
Reply

2,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Bela on Fri Jul 10 06:13:39 MST 2015
Thank You, R2D2!
My program works already!

Just one more question, please:

If I single step through my Timer0 IT handler, there's a point, when the IT request must be cleared.

I do it by the following instruction:
LPC_TIMER0->IR = (1<<0) ; // this must clear the Timer0 Match0 IT request.

The program works, therefore this IT bit is probably cleared. But look at the screenshot please: TIMER0->IR->MR0I bit remained 1.

Shouldn't it show me 0?
0 Kudos
Reply

2,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Thu Jul 09 13:36:02 MST 2015
Then try to write your program in C:

void Timer0Match0IT (void)// This IT service routine switches the red LED OFF.
 {
//LPC_TIMER0->IR = 0x1<<0; // clear IT request;
//dummyroutine();
SwitchRedLed(0);// Turn off red LED
SwitchGreenLed(0);
SwitchBlueLed(0);
 }

void Timer0Match1IT (void)// This IT service routine has to switch the 3 LEDs ON and clears TIMER0.
{
//LPC_TIMER0->IR |= (1<<1); // clear IT request
SwitchRedLed(1);
SwitchGreenLed(1);
//SwitchBlueLed(1);
}
/*
void Timer0Match2IT (void)// This IT service routine switches the Green LED OFF.
{
LPC_TIMER0->IR |= (1<<2); // clear IT request;
SwitchGreenLed(0);// Turn off green LED
}

void Timer0Match3IT (void)// This IT service routine switches the Blue LED OFF.
{
LPC_TIMER0->IR |= (1<<3); // clear IT request;
SwitchBlueLed(0);// Turn off red LED
}*/
/*void TIMER0_IRQHandler(void)
{
if (Chip_TIMER_MatchPending(LPC_TIMER0, 1)) {
Chip_TIMER_ClearMatch(LPC_TIMER0, 1);
Board_LED_Toggle(0);
}
}*/
void TIMER0_IRQHandler (void)
{
 NVIC_ClearPendingIRQ(TIMER0_IRQn);
 if(LPC_TIMER0->IR & (1<<0))// if Timer0 Match0 resulted an IT
 {
  LPC_TIMER0->IR = (1<<0);// clear IT request
  Timer0Match0IT();// then call Timer0Match0IT
 }
 if(LPC_TIMER0->IR & (1<<1))// if Timer0 Match1 resulted an IT
 {
  LPC_TIMER0->IR = (1<<1);// clear IT request
  Timer0Match1IT();// then call Timer0Match1IT service routine
 }
}
0 Kudos
Reply

2,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Bela on Thu Jul 09 13:01:14 MST 2015
Attached is Proba04.zip
This is the whole project :-)
Everything seems to work but Timer0 interrupt. And I cannot find out, why the Timer0Match1IT never called.
0 Kudos
Reply

2,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Thu Jul 09 12:24:43 MST 2015

Quote:
Earlier I also tried this, but also didn't work...



Could be useful to post a complete project...


0 Kudos
Reply

2,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Bela on Thu Jul 09 11:53:31 MST 2015
> LPC_TIMER0->IR |= (1<<0); // clear IT request

Doesn't this write a 1 into the IT request bit?

Earlier I also tried this, but also didn't work:

LPC_TIMER0->IR = 0x1<<0;

At least if I single step through in LPCXpresso, the bit remains unchanged, always 1. At the very begin of the program it is still 0.
0 Kudos
Reply

2,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Thu Jul 09 11:45:16 MST 2015

Quote: Bela
What is the proper way to delete the Timer0Match0 interrupt? (Yes, I read in the manual: I have to write a 1 into the corresponding register.



And why don't you do it  :quest:


LPC_TIMER0->IR |= (1<<0); // clear IT request
0 Kudos
Reply

2,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Bela on Thu Jul 09 11:36:21 MST 2015
LPC1769
0 Kudos
Reply

2,368 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by R2D2 on Thu Jul 09 11:28:17 MST 2015
Any hint which MCU we are talking about?
0 Kudos
Reply