chipKIT® Development Platform

Inspired by Arduino™

[SOLVED] Max32 : Timer interrupt hangs

Created Sun, 15 Dec 2013 17:12:33 +0000 by Adonosonix


Adonosonix

Sun, 15 Dec 2013 17:12:33 +0000

Hi,

I tried to set a timer interrupt, to do some work periodically, but I can't make it work. It hangs on the first time it fires.

Here is the code I use to setup the interrupt

//timer 3 set clock period 20ms
	T3CON = 0x0060; // set prescalar 1:64
	TMR3 = 0;
	PR3 = 0x61A8;

	IFS0CLR = 0x1000;// Clear the T3 interrupt flag
	IEC0SET = 0x1000;// Enable T3 interrupt

	IPC3CLR = 0x0000001F;
	IPC3SET = (_T3_IPL_IPC << 2) | _T3_SPL_IPC;

	T3CONSET = 0x8000;// Enable Timer3

Here is the interrupt handler

extern "C"
{
	void __ISR(_TIMER_3_VECTOR,ipl3) pwmOn(void)
	{
		IFS0CLR  = 0x00001000;  // Clear Timer interrupt status flag
		IEC0SET  = 0x00001000;  // Enable Timer interrupts
		return;
	}
}

I tried various combination of values to clear the interrupt… I can't make it work.

Using a serial print statement on the loop() function, I can see that the program hangs after the first call to the interrupt.

What's wrong?

Additional info: I am running a web server on the board.


majenko

Sun, 15 Dec 2013 17:56:31 +0000

IPC3SET = (_T3_IPL_IPC << 2) | _T3_SPL_IPC;
...
   void __ISR(_TIMER_3_VECTOR,ipl3) pwmOn(void)

_T3_IPL_IPC is 4, not 3, so your ISR isn't being called as it's at IPL3 not 4.


Adonosonix

Sun, 15 Dec 2013 18:42:50 +0000

Thank you so much for your reply. I have looked at the definitions, and I feel quite lost.

#define	_T1_IPL_ISR	ipl3
#define	_T1_IPL_IPC	3
#define	_T1_SPL_IPC	0

So, I should use _T1_IPL_xxxxx with ipl3 everywhere ?

Also, I would like to trigger every 15 seconds. I have read the documentation, but I do not understand how :

T3CON = 0x0060; // set prescalar 1:64

can relate to 1:60

and

T3CON = 0x8030;

makes 1:256

How does that work ?


majenko

Sun, 15 Dec 2013 18:56:20 +0000

Thank you so much for your reply. I have looked at the definitions, and I feel quite lost.

#define	_T1_IPL_ISR	ipl3
#define	_T1_IPL_IPC	3
#define	_T1_SPL_IPC	0

So, I should use _T1_IPL_xxxxx with ipl3 everywhere ?

No, for Timer 3 you should use _T3_IPL_xxx and ipl4 everywhere.

Also, I would like to trigger every 15 seconds. I have read the documentation, but I do not understand how :

T3CON = 0x0060; // set prescalar 1:64

can relate to 1:60 and

T3CON = 0x0070;

makes 1:256 How does that work ?

Have you read the Timers manual from the PIC32 FRM? [url]http://ww1.microchip.com/downloads/en/DeviceDoc/61105F.pdf[/url]

TxCON: bit 6-4: TCKPS<2:0>: Timer Input Clock Prescale Select bits 111 = 1:256 prescale value 110 = 1:64 prescale value 101 = 1:32 prescale value 100 = 1:16 prescale value 011 = 1:8 prescale value 010 = 1:4 prescale value 001 = 1:2 prescale value 000 = 1:1 prescale value

Bits 6 to 4, in binary, are 0000000000***0000 So that is between 00000000000000000 and 00000000001110000 Which, in hexadecimal is between 0x0000 and 0x0070 So the 0x60 is 0x0060, which is 0000000001100000 so bits 6-4 are 110, which in that table is 1:64 prescaler.

At 80MHz, with a 1:256 prescaler, the timer ticks at 312500 Hz. With a period of 0xFFFF that equates to 4.768 Hz, or ~0.2 seconds - the longest period you can "tick" with a single timer ISR.

You could tie two timers together into a single 32-bit timer, which would allow you to time for much longer periods, but TBH it's easiest just to tick for a regular shorter period and use a simple counter to further sub-divide it. Say tick at 10Hz, then count the number of 0.1 second interrupts till you reach your desired period.


Adonosonix

Sun, 15 Dec 2013 19:28:59 +0000

Again thank you so much for your reply. Actually, the documentation I read was this one : http://www.mikroe.com/chapters/view/52/chapter-4-timers/

Counting the interrupts is a great idea. Thank you.

I did some tests before reading your answer, and I made it work with

T3CON = 0x0060;
	TMR3 = 0;
	PR3 = 0x61A8;

	IFS0CLR = 0x1000;
	IEC0SET = 0x1000;

	IPC3CLR = 0x0000001F;
	IPC3SET = (_T1_IPL_IPC &lt;&lt; 2) | _T1_SPL_IPC;

	T3CONSET = 0x8000;
void __ISR(_TIMER_3_VECTOR,ipl3) pwmOn(void)
	{
		Serial.print("I");

		IFS0CLR  = 0x00001000;  // Clear Timer interrupt status flag
		IEC0SET  = 0x00001000;  // Enable Timer interrupts
	}

So, I am not using timer 3 ? Are any of the timers free to choose ? Or do I need to avoid some of them, because they have internal use or are use with the "defaults" frameworks?


majenko

Sun, 15 Dec 2013 20:10:32 +0000

You're using timer 3 but with timer 1's priority. It shouldn't cause a problem, but it's confusing to someone reading it.

If you want to use some other priority than priority 4 then you should really use a literal 3 instead of a symbol relating to another peripheral.

Timer 1 is used by the tone() command, and Timer 2 is used by PWM. All other timers are free to be used as you like.


Adonosonix

Sun, 15 Dec 2013 21:10:02 +0000

Majenko. Thank you so much for your help. I have modified the code accordingly. Thanks again.