|
|
View previous topic :: View next topic |
Author |
Message |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
Bug? Fast interrupts incompatible with option noclear? |
Posted: Thu May 06, 2004 7:28 am |
|
|
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? |
Posted: Thu May 06, 2004 1:19 pm |
|
|
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 |
Posted: Thu May 06, 2004 9:12 pm |
|
|
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
|
|
Posted: Fri May 07, 2004 4:19 am |
|
|
Thanks for the replies!
It turns out that I do have an issue here because even TTelmah has it wrong.
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
|
|
Posted: Fri May 07, 2004 5:16 am |
|
|
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
|
|
Posted: Sat May 08, 2004 2:40 am |
|
|
ckielstra wrote: | Thanks for the replies!
It turns out that I do have an issue here because even TTelmah has it wrong.
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
|
|
Posted: Mon May 10, 2004 1:07 am |
|
|
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
|
|
Posted: Mon May 10, 2004 3:03 am |
|
|
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
|
|
Posted: Mon May 10, 2004 10:07 am |
|
|
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: 70 Location: West Sussex, UK
|
|
Posted: Mon May 10, 2004 2:13 pm |
|
|
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: 70 Location: West Sussex, UK
|
|
Posted: Mon May 10, 2004 2:16 pm |
|
|
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
|
|
Posted: Mon May 10, 2004 2:55 pm |
|
|
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: 70 Location: West Sussex, UK
|
|
Posted: Mon May 10, 2004 3:32 pm |
|
|
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 _________________ Peter Willis
Development Director
Howard Eaton Lighting Ltd UK |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue May 11, 2004 12:59 am |
|
|
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: 70 Location: West Sussex, UK
|
|
Posted: Tue May 11, 2004 2:18 am |
|
|
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 |
|
|
|
|
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
|