C161P Timer Interrupt doesn't escape from IDLE, Should it?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
Using SAF-C161PI-LF3VCA

Timer 6 is configured to interrupt every 5 ms. An external interrupt is also enabled. Both interrupts work! However,
if I insert an _idle_() instruction into my program only the external interrupt causes a return from idle.

Should Timer 6 interrupt make the program leave idle?
Is there something else apart from enabling T6IE and global interrupts I have to do to make it work?
0 Likes
1 Reply
Not applicable
The system was entering sleep mode and not idle. In Idle mode only the CPU is stopped. In Sleep mode both the CPU and the peripherals are stopped. Thus the
TIMER6 was stopped and couldn't interrupt.

This happened because the Bootloader which runs prior to launching the application was setting bitfield SLEEPCON in register SYSCON1 which causes the
_idle_() instruction to force sleep mode rather than idle mode. The Bootloader also executed the EINIT instruction which locks access to the power management
control registers (SYSCON1, SYSCON2, SYSCON3).

I can't change the Bootloader.

The solution to make the _idle_() instruction enter idle mode rather than to sleep mode is to clear the SLEEPCON bitfield in register SYSCON1 after first unlocking it.

The Keil C166 'C' compiler allows in line assembler so I just put the following lines at the start of my "main" function and now it works as I want.

	//clear SYSCON1
__asm
{
EXTR #4H ;Switch to ESFR space and lock sequence
BFLDL SYSCON2,#0FH,#09H ;Unlock sequence, step 1 (1001B)
MOV SYSCON2,#0003H ;Unlock sequence, step 2 (0011B)
BSET SYSCON2.2 ;Unlock sequence, step 3 (0111B)
BFLDL 0xF1DC,#01H,#00H ;clear low byte SYSCON1 bit zero
}
0 Likes