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

Bug? Fast interrupts incompatible with option noclear?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

Bug? Fast interrupts incompatible with option noclear?
PostPosted: Thu May 06, 2004 7:28 am     Reply with quote

I get a compiler error 'Invalid Pre-Processor directive' when combining the two parameters NOCLEAR and FAST for my interrupt handler. Am I doing something wrong? Leaving out one of the two parameters makes the code compilable.

I'm using PCH v3.187 for an PIC18F458.


example
Code:
#INT_EXT NOCLEAR FAST
void ext0_isr()
{
  // some code
}
Ttelmah
Guest







Re: Bug? Fast interrupts incompatible with option noclear?
PostPosted: Thu May 06, 2004 1:19 pm     Reply with quote

ckielstra wrote:
I get a compiler error 'Invalid Pre-Processor directive' when combining the two parameters NOCLEAR and FAST for my interrupt handler. Am I doing something wrong? Leaving out one of the two parameters makes the code compilable.

I'm using PCH v3.187 for an PIC18F458.


example
Code:
#INT_EXT NOCLEAR FAST
void ext0_isr()
{
  // some code
}

Yes, they are incompatible.
The interrupt 'clearing', is done in the 'int_global' routine. When you use 'fast', _you_ are effectively providing the int_global handler for the fast interrupt. This is why it becomes your responsibility to clear the interrupt yourself (hence the 'NOCLEAR' option, which normally leaves this to you, would do nothing), and also it becomes your responsibility to save _all_ registers that are used inside the fast handler....

Best Wishes
C-H Wu
Guest







For _fast_ interrupt, the flag is _always_ cleared by CCS
PostPosted: Thu May 06, 2004 9:12 pm     Reply with quote

For _normal_ interrupt, whether the interrupt flag be cleared by CCS before returning to main() can be controlled by the _noclear_ directive.

For _fast_ interrupt, the interrupt flag is _always_ cleared by CCS before returning to main(). This is why the _noclear_ directive become invalid for _fast_ interrupt.

Read the .LST file and you will find it there. The flag clearing is a simple instruction like this ... BCF INTCON, 2 ... say, for TIMER0

Best regards
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri May 07, 2004 4:19 am     Reply with quote

Thanks for the replies!

It turns out that I do have an issue here because even TTelmah has it wrong. Confused

It's a bit confusing that for a fast-interrupt you have to do everything yourself, except for the clearing of the interrupt.

Ofcourse the interrupt must be cleared, but sometimes I want to control it myself. Why allowing this directive for normal interrupts, but not for the fast interrupt? I don't like exceptions because they make things more difficult.

It's easy to workaround, but what would be a good reason for CCS not implementing the NOCLEAR directive?
jaremek
Guest







PostPosted: Fri May 07, 2004 5:16 am     Reply with quote

I have used my own procedure for 3 years and I can do manually all what I need:

Code:
//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//--------------------------   source code     -------------------------------
#INT_GLOBAL
void isr()  {
   int temp_inter, temp_inter1, temp_inter2;

   #asm
   //store current state of processor
   MOVFF WREG,save_w
   MOVFF   STATUS,save_status
   MOVFF   BSR,save_bsr
   MOVFF   FSR0L,save_fsr0l
   MOVFF   FSR0H,save_fsr0h
   MOVLB   0
   MOVF   00,W
   MOVWF   save_sch0
   MOVF   01,W
   MOVWF   save_sch1
   MOVF   02,W
   MOVWF   save_sch2
   MOVF   03,W
   MOVWF   save_sch3
   MOVF   04,W
   MOVWF   save_sch4
   #endasm
   // code for isr
   //; Now check manualy interrupt bits and remember to clear this bit
   //; _T0IF    -Timer0 overflow
   //; _RCIF   -Receive buffer is full (USART)
   //; _TXIF   -transmit buffer is empty
   //; _ADIF   -A/D conversion completed

   if (!_T0IF)         //; !!! Timer0 overflow
   goto   End_int_t0;   //; other interrupt
//; --------------------  Interrupt by TIMER 0  -------------------------
   _T0IF=0;
   ...............
   ...............
End_int_t0:
//; --------------------  END Interrupt by TIMER 0  -------------------------

#ifdef   RS232_REC_ON
   if (!_RCIF)
   goto   End_int_rc;
//; --------------------  Interrupt by reciver of USART  -----------------------
   _RCIF=0;
   ...............
   ...............
   goto   End_int;

End_int_rc:
//; --------------------  END Interrupt by reciver of USART  ------------------
#endif

//; --------------------  Interrupt in future  -------------------------

End_int:               // now you have to recovery FSR, PCLATH, STATUS and W register
   #asm
   MOVF   save_sch0,W
   MOVWF   00
   MOVF   save_sch1,W
   MOVWF   01
   MOVF   save_sch2,W
   MOVWF   02
   MOVF   save_sch3,W
   MOVWF   03
   MOVF   save_sch4,W
   MOVWF   04
   MOVFF   save_fsr0h,FSR0H
   MOVFF   save_fsr0l,FSR0L
   MOVFF   save_bsr,BSR
   MOVFF save_w,WREG
   MOVFF   save_status,STATUS
   #endasm
}

Maybe it will be useful for you too.
Ttelmah
Guest







PostPosted: Sat May 08, 2004 2:40 am     Reply with quote

ckielstra wrote:
Thanks for the replies!

It turns out that I do have an issue here because even TTelmah has it wrong. Confused

It's a bit confusing that for a fast-interrupt you have to do everything yourself, except for the clearing of the interrupt.

Ofcourse the interrupt must be cleared, but sometimes I want to control it myself. Why allowing this directive for normal interrupts, but not for the fast interrupt? I don't like exceptions because they make things more difficult.

It's easy to workaround, but what would be a good reason for CCS not implementing the NOCLEAR directive?


You can do it dead easily. I had forgotten that it was clared, because when I played with 'fast', it was back at the time when 'RETFIE1' wasn't understood by the compiler, so I ended up doing a #ROM directive, and overwriting the last few bytes of th handler generated by the compiler. I then had to 'abandon' FAST, because on the 18Fxx2 family, it is largely unuseable, becuse of the limitation (on all but the latest chip releases now), with using it for an asynchronous event.
If you want to clear it yourself, just clear it inside the handler, and add a:
#ASM
RETFIE 1
#ENDASM

at the end of your code, which then bypasses the internal 'clear' operation.

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon May 10, 2004 1:07 am     Reply with quote

Thanks Ttelmah, that's another work around that I hadn't thought off.

But it's still an unnecesary workaround requiering 4 additional program bytes. I will ask CCS to add the noclear directive.

Thinking about it, there are more issues about the Fast interrupt setup that I'm not happy about. For example, it requires some trickery to setup a single interrupt handler for 2 high priority interrupt sources, e.g. EXT0 and EXT1.

The current implementation of the Fast interrupts by CCS has similarities with the #int_global implementation where you have to write your own interrupt dispatcher. Maybe we should ask CCS for an #int_global_fast??? But then, how to specify the interrupt level? Maybe an extra parameter to the enable_interrupts() function?
Ttelmah
Guest







PostPosted: Mon May 10, 2004 3:03 am     Reply with quote

ckielstra wrote:
Thanks Ttelmah, that's another work around that I hadn't thought off.

But it's still an unnecesary workaround requiering 4 additional program bytes. I will ask CCS to add the noclear directive.

Thinking about it, there are more issues about the Fast interrupt setup that I'm not happy about. For example, it requires some trickery to setup a single interrupt handler for 2 high priority interrupt sources, e.g. EXT0 and EXT1.

The current implementation of the Fast interrupts by CCS has similarities with the #int_global implementation where you have to write your own interrupt dispatcher. Maybe we should ask CCS for an #int_global_fast??? But then, how to specify the interrupt level? Maybe an extra parameter to the enable_interrupts() function?


The problem is, that if you want to use 'fast', you are presumably doing this because you want 'fast' behaviour, and the ability to interrupt another event. The fastest way of working, is to only save the registers that your routine needs. Since this will vary with the handler, adding a default global handler, perhaps making some 'assumptions' about what registers are needed, will negate a lot of the advantages of using the fast event....
What I'd like to see, would be a set of macros offered for use in the 'fast' handler, and the default 'clear' removed. The first 'set' of macros would save all registers (don't use this unless you have to...), but a couple of smaller ones, one which saves the 'scratch' area (allowing you to use arithmetic functions), one which saves the table pointers (needed for arrays) etc.. Then a couple that allow you to check for interrupt events, and jump to them (so 'check_for(#int_RTCC)', would allow code like:

Code:

if (check_for(#int_RTCC)) {
    //Interrupt handler for RTCC event
    clear_interrupt(#int_RTCC);
    //your code here
}


These would make writting a 'multi interrupt' FAST handler a 'doddle', and would be similarly useful when doing normal int_GLOBAL code..
Except for the 'clear', the current 'fast' handler is fine for multiple interrupts (with a check_for ability added). The problem is that the 'slow' handler will check for an interrupt unless it is flagged as fast...

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon May 10, 2004 10:07 am     Reply with quote

Quote:
Except for the 'clear', the current 'fast' handler is fine for multiple interrupts (with a check_for ability added).


So, I'll ask for a noclear parameter, just like in the low-priority interrupts.
The macro's you suggest are nice, but not something I think essential to the compiler. They are also easy to create yourself.

Quote:
The problem is that the 'slow' handler will check for an interrupt unless it is flagged as fast...

I tried this, but in PCH v3.187 it looks like this is no problem. I couldn't find a 'slow' handler for my timer2 interrupt (cleared by my combined 'fast' EXT0 handler).
prwatCCS



Joined: 10 Dec 2003
Posts: 67
Location: West Sussex, UK

View user's profile Send private message

PostPosted: Mon May 10, 2004 2:13 pm     Reply with quote

Is there a way of telling the FAST interrupt handler to return with a RETFIE 1 rather than RETFIE 0 ?

Obviously, my interim workaround is (for a Timer2 Fast irq)
Code:

#int_TIMER2 FAST
TIMER2_isr()
{

....

   CLEAR_INTERRUPT(INT_TIMER2);
#asm
   RETFIE 1
#endasm
}



I am proposing to rely on the processors ability (for the 18Fxx2) to context save and restore W and STATUS, which is why I want the RETFIE 1.

Does anyone have any experience of this ??
_________________
Peter Willis
Development Director
Howard Eaton Lighting Ltd UK
prwatCCS



Joined: 10 Dec 2003
Posts: 67
Location: West Sussex, UK

View user's profile Send private message

PostPosted: Mon May 10, 2004 2:16 pm     Reply with quote

A while back, Ttelma wrote
Quote:

You can do it dead easily. I had forgotten that it was clared, because when I played with 'fast', it was back at the time when 'RETFIE1' wasn't understood by the compiler, so I ended up doing a #ROM directive, and overwriting the last few bytes of th handler generated by the compiler. I then had to 'abandon' FAST, because on the 18Fxx2 family, it is largely unuseable, becuse of the limitation (on all but the latest chip releases now), with using it for an asynchronous event


Can someone please explain what this limitation is/was in relation to async events ??

thanks
_________________
Peter Willis
Development Director
Howard Eaton Lighting Ltd UK
Ttelmah
Guest







PostPosted: Mon May 10, 2004 2:55 pm     Reply with quote

prwatCCS wrote:
A while back, Ttelma wrote
Quote:

You can do it dead easily. I had forgotten that it was clared, because when I played with 'fast', it was back at the time when 'RETFIE1' wasn't understood by the compiler, so I ended up doing a #ROM directive, and overwriting the last few bytes of th handler generated by the compiler. I then had to 'abandon' FAST, because on the 18Fxx2 family, it is largely unuseable, becuse of the limitation (on all but the latest chip releases now), with using it for an asynchronous event


Can someone please explain what this limitation is/was in relation to async events ??

thanks

Read the errata sheet for the chips...
Basically for example, on the 18F452, is an asynchronous 'high priority' interrupt occurs one cycle after a low priority interrupt, the stack can get incorrectly 'double pushed', and will eventually overflow. There is another variant, resulting in the loss of one instruction on another chip. It is only the latest silicon revisions on these chips, that allow both interrupt levels to be used properly.
Seperately, I have never understood MicroChips 'logic', in the layout of the handler addresses. If they made the low priority handler locate at the low address, rather than the high address, the whole code for the high priority handler could be written without the need for the extra 'jump' that is otherwse needed, saving one instruction.

Best Wishes
prwatCCS



Joined: 10 Dec 2003
Posts: 67
Location: West Sussex, UK

View user's profile Send private message

PostPosted: Mon May 10, 2004 3:32 pm     Reply with quote

thanks - I had been looking at the rev C0 errata sheet, which makes no mention of the problem, whereas the revB5 (and earlier) did. So presumably it has been fixed Smile
_________________
Peter Willis
Development Director
Howard Eaton Lighting Ltd UK
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue May 11, 2004 12:59 am     Reply with quote

Quote:
Is there a way of telling the FAST interrupt handler to return with a RETFIE 1 rather than RETFIE 0 ?


My PCH v3.187 is doing this.


I received a reply from CCS that the NOCLEAR directive will be added to the next release (3.191?).
prwatCCS



Joined: 10 Dec 2003
Posts: 67
Location: West Sussex, UK

View user's profile Send private message

PostPosted: Tue May 11, 2004 2:18 am     Reply with quote

My 3.190 appears not to ! (Nor does v3.188)
extract from list file

.................... #int_TIMER2 FAST
.................... TIMER2_isr()

08E2: NOP(FFFF)
.................... output_bit(PWM_5,1); //debug
08E4: BSF F8B.1
....................
08E6: BCF F9E.1
08E8: RETFIE 0

BUT GUESS WHAT - it did in v3.185

extract from list file - compiled from same source

08FC: NOP(FFFF)
.................... output_bit(PWM_5,1); //debug
08FE: BSF F8B.1
....................
0900: BCF F9E.1
0902: RETFIE 1

Has CCS changed something else and not mentioned it ?
_________________
Peter Willis
Development Director
Howard Eaton Lighting Ltd UK
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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