CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Interruption loops ... despite flag clear

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
tssir



Joined: 14 Feb 2016
Posts: 24

View user's profile Send private message

Interruption loops ... despite flag clear
PostPosted: Wed Sep 07, 2016 3:10 pm     Reply with quote

Hello,

My interruption handler loops. Despite interruption flag clearing code is presents.

Compiler version 5.043
PIC16F1705, standard run mode at 3.3V

My test code :
Code:

#include <16F1705.h>
#fuses INTRC_IO,WDT_SW,NOPUT,NOMCLR,PROTECT,BROWNOUT,BORV25,NOCLKOUT,NOIESO,NOFCMEN,NOWRT,NOPPS1WAY,NOZCDDIS,NOPLLEN,NOSTVREN,NOLPBOR,NODEBUG,NOLVP
#use delay(clock=32MHZ)

#USE fast_io(A)
#USE fast_io(C)

#define   IO_LED PIN_A2

#define TRIS_A    (0b00010011)
#define PULLUPS_A (0b00010011)
#define TRIS_C    (0b00011111)
#define PULLUPS_C (0b00011111)

// --------------------------------------------------------------------------------------
#define LED_OFF TRUE
#define LED_ON FALSE
// --------------------------------------------------------------------------------------
unsigned int8 i;
// --------------------------------------------------------------------------------------
#byte IOCAF=getenv("SFR:IOCAF")
#byte IOCCF=getenv("SFR:IOCCF")
#INT_RA
void handler_ra(void)
{
// Rapid blink
output_bit(IO_LED,LED_ON); delay_ms(50);
output_bit(IO_LED,LED_OFF); delay_ms(250);
output_bit(IO_LED,LED_ON); delay_ms(50);
// Read input for automatic flag clear
i=input_a();
// Useless manual clear by ccs function, for test
clear_interrupt(INT_RA); // Useless, not concern, for test
clear_interrupt(INT_RA0);
clear_interrupt(INT_RA1);
IOCAF=0; // Useless (only & operation allowed for IOCxF), for test
}
#INT_RC
void handler_rc(void)
{
// Rapid blink
output_bit(IO_LED,LED_ON); delay_ms(50);
output_bit(IO_LED,LED_OFF); delay_ms(250);
output_bit(IO_LED,LED_ON); delay_ms(50);
// Read input for automatic flag clear
i=input_c();
// Useless manual clear by ccs function, for test
clear_interrupt(INT_RC); // Useless, not concern, for test
clear_interrupt(INT_RC0);
clear_interrupt(INT_RC1);
clear_interrupt(INT_RC2);
clear_interrupt(INT_RC3);
clear_interrupt(INT_RC4);
clear_interrupt(INT_RC5);
IOCCF=0; // Useless (only & operation allowed for IOCxF), for test
}
// --------------------------------------------------------------------------------------
void main(void)
{
setup_wdt(WDT_OFF); // Disable WDT to prevent CPU reset before first sleep
set_tris_a(TRIS_A);
set_tris_c(TRIS_C);
port_a_pullups(PULLUPS_A);
port_c_pullups(PULLUPS_C);

// Need to scan RC0-5 RA0-1
enable_interrupts(INT_RC5);
enable_interrupts(INT_RC4);
enable_interrupts(INT_RC3);
enable_interrupts(INT_RC2);
enable_interrupts(INT_RC1);
enable_interrupts(INT_RC0);
enable_interrupts(INT_RA1);
enable_interrupts(INT_RA0);

output_bit(IO_LED,LED_OFF);

// Two long blinks
output_bit(IO_LED,LED_OFF); delay_ms(500);
output_bit(IO_LED,LED_ON); delay_ms(500);
output_bit(IO_LED,LED_OFF); delay_ms(500);
output_bit(IO_LED,LED_ON); delay_ms(500);
output_bit(IO_LED,LED_OFF);

// Setup WDT to out from sleep or reset if stucked
setup_wdt(WDT_1S+WDT_ON);
enable_interrupts(GLOBAL);
while(true)
   {
   // Wait for interrupt or WDT
   sleep();
   output_bit(IO_LED,LED_OFF);
   }
}


CCS compiling seem not bad :
Code:

.................... void handler_ra(void)
.................... {
.................... // Rapid blink
.................... output_bit(IO_LED,LED_ON); delay_ms(50);
0039:  MOVLB  02
003A:  BCF    0C.2
003B:  MOVLW  32
003C:  MOVLB  00
003D:  MOVWF  28
003E:  CALL   024
.................... output_bit(IO_LED,LED_OFF); delay_ms(250);
003F:  MOVLB  02
0040:  BSF    0C.2
0041:  MOVLW  FA
0042:  MOVLB  00
0043:  MOVWF  28
0044:  CALL   024
.................... output_bit(IO_LED,LED_ON); delay_ms(50);
0045:  MOVLB  02
0046:  BCF    0C.2
0047:  MOVLW  32
0048:  MOVLB  00
0049:  MOVWF  28
004A:  CALL   024
.................... // Read input for automatic flag clear
.................... i=input_a();
004B:  MOVF   0C,W
004C:  MOVWF  25
.................... // Useless manual clear by ccs function, for test
.................... clear_interrupt(INT_RA); // Useless, not concern, for test
004D:  MOVF   0E,W
.................... clear_interrupt(INT_RA0);
004E:  MOVLB  07
004F:  BCF    13.0
.................... clear_interrupt(INT_RA1);
0050:  BCF    13.1
.................... IOCAF=0; // Useless (only & operation allowed for IOCxF), for test
0051:  CLRF   13
.................... }
0052:  MOVLW  FF
0053:  XORWF  13,W
0054:  ANDWF  13,F
0055:  BCF    0B.0
0056:  MOVLP  00
0057:  MOVLB  00
0058:  GOTO   017


CCS injects a propper interruption flag clear (i think) :
Code:

0052:  MOVLW  FF
0053:  XORWF  13,W
0054:  ANDWF  13,F


Running behaviour :
Start with two long led blinks. Wait for an input state change.
If i change an input, i can see some rapid blinks. After a second, two long blinks.
Some rapid blinks means that interruption raised and handler code is executed, but it loops until WDT reset the CPU (one second after last sleep).
Normal behaviour is one handler execution, off the led, and go sleep again.

Why my interruption handler code loops ? I read many interruption/CCS problems on this forum. But I can't see why my code not working. Any idea ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Sep 07, 2016 3:42 pm     Reply with quote

Quote:
#define TRIS_C (0b00011111)
#define PULLUPS_C (0b00011111)

In the code above, you have TRIS set to output and pull-ups disabled for
pin C5. But in the code below, you are using pin C5. It's not going
to work correctly for that pin with the pullups turned off and the TRIS set
to output.
Quote:

// Need to scan RC0-5 RA0-1
enable_interrupts(INT_RC5);
enable_interrupts(INT_RC4);
enable_interrupts(INT_RC3);
enable_interrupts(INT_RC2);
enable_interrupts(INT_RC1);
enable_interrupts(INT_RC0);
enable_interrupts(INT_RA1);
enable_interrupts(INT_RA0);



Also in my version of the compiler 5.061, it allows selecting which edge
to interrupt on (rising or falling). Do you want to interrupt on both edges ?
Your code is currently setup for that.
Code:
#define INT_RC5                   0x32200B08
#define INT_RC5_L2H               0x12200B08
#define INT_RC5_H2L               0x22200B08
temtronic



Joined: 01 Jul 2010
Posts: 9162
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Sep 07, 2016 4:05 pm     Reply with quote

As said many, many times before ...it's a really, really BAD idea to have ANY delays in ANY ISR..

It defeats the reason to use an ISR....


Jay
tssir



Joined: 14 Feb 2016
Posts: 24

View user's profile Send private message

PostPosted: Thu Sep 08, 2016 12:27 am     Reply with quote

Correct. I add C5 tris and pullup.

Currently, without any settings, it raise interrupt on both edges. I need this behavior.
I try with INT_RC4_L2H and INT_RC4_H2L. It has no influence about interruption clear :
Code:
.................... clear_interrupt(INT_RC4);
0073:  BCF    19.4
.................... clear_interrupt(INT_RC4_L2H);
0074:  BCF    19.4
.................... clear_interrupt(INT_RC4_H2L);
0075:  BCF    19.4


@temtronic : You are true. Original interruption code :
Code:

#INT_RA
void handler_ra(void)
{
i=input_a();
wakeupIsInterruption=true;
clear_interrupt(INT_RA0);
clear_interrupt(INT_RA1);
}

Set wakeupIsInterruption global variable, and wakeup from sleep. That's all I expect from this interruption.
tssir



Joined: 14 Feb 2016
Posts: 24

View user's profile Send private message

PostPosted: Thu Sep 08, 2016 1:00 am     Reply with quote

I found a clue ...

It seems that both interruptions are mixed.
On RC changes, #INT_RA is called.
I try this code :
Code:

#INT_RA
void handler_ra(void)
{
// Rapid blink
output_bit(IO_LED,LED_ON); delay_ms(50);
output_bit(IO_LED,LED_OFF); delay_ms(100);
output_bit(IO_LED,LED_ON);
// Read input for automatic flag clear
i=input_a();
clear_interrupt(INT_RA0);
clear_interrupt(INT_RA1);
clear_interrupt(INT_RC0);
clear_interrupt(INT_RC1);
clear_interrupt(INT_RC2);
clear_interrupt(INT_RC3);
clear_interrupt(INT_RC4);
clear_interrupt(INT_RC5);
}
#INT_RC
void handler_rc(void)
{
i=input_c();
}

Then ... it works ! No more loops.
After some tries, it seems that any state changes on RA and RC raise #INT_RA. Never #INT_RC. Then i need to clear INT_RCx flags on #INT_RA too.
Luckily, both interruptions do sames things, on my design. It is a good solution for me.

For your information, interruption setup code :
Code:

.................... enable_interrupts(INT_RC5);
0075:  BSF    0B.3
0076:  MOVLB  07
0077:  BSF    17.5
0078:  BSF    18.5
.................... enable_interrupts(INT_RC4);
0079:  BSF    0B.3
007A:  BSF    17.4
007B:  BSF    18.4
.................... enable_interrupts(INT_RC3);
007C:  BSF    0B.3
007D:  BSF    17.3
007E:  BSF    18.3
.................... enable_interrupts(INT_RC2);
007F:  BSF    0B.3
0080:  BSF    17.2
0081:  BSF    18.2
.................... enable_interrupts(INT_RC1);
0082:  BSF    0B.3
0083:  BSF    17.1
0084:  BSF    18.1
.................... enable_interrupts(INT_RC0);
0085:  BSF    0B.3
0086:  BSF    17.0
0087:  BSF    18.0
.................... enable_interrupts(INT_RA1);
0088:  BSF    0B.3
0089:  BSF    11.1
008A:  BSF    12.1
.................... enable_interrupts(INT_RA0);
008B:  BSF    0B.3
008C:  BSF    11.0
008D:  BSF    12.0
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group