View previous topic :: View next topic |
Author |
Message |
Joyce Guest
|
Fast interrupts on PIC18F452, CCS PCH 3.186 |
Posted: Wed May 12, 2004 12:27 pm |
|
|
On my project I'm using PIC18F452 to deal with 3 interrupts so far:
INT_EXT0
INT_EXT1
INT_TIMER1
The requirement is to execute EXT0 and EXT1 as fast as possible (6.5 us to have an SPI read/write). By default the EXT0 interrupt is a high priority interrupt. The rest could be set as high or low. I was thinking to have something like this:
#INT_EXT FAST
void CPLD_RW_Byte_Isr(void)
{
do stuff;
C_Function_Call();
do some more stuff;
}
#int_TIMER1
void TIMER1_isr(void)
{
Tmr1Timeout = TRUE;
}
#INT_EXT1
void Flag_Detect_Isr(void)
{
A = 0;
B = 1;
}
If I'm using the FAST keyword the BSR, STATUS and W are saved in shadow registers and restored when the ISR is done. I didn't see any code generated for saving other registers. The compiler generates a single GOTO at address 0x8 (high priority vector) to my fast interrupt. Address 0x18 (low priority vector) has the dispacher for the rest of the interrupts.
The #priority keyword just change the position of the EXT1 and TIMER1 in the dispatch table.
From what I read so far there were some suggestions that is not advisable to have C functions calls from the FAST interrupt. Why ? In my case I really need to have that. What should be done to accomodate this ?
If you are still reading I guess you can tell that I'm a bit confused.
What can I do to have the ISRs safe ?
Do I need for my project configuration to use #INT_GLOBAL instead of individual declared #INT_XXX ?
Where should I save the extra registers (in the fast isr) ? Some example would help...The problem with that is that I have no idea which registers should be saved. If I'm gonna save too many then the ISR will get longer and probablly I'll loose my deadline.
Any help/reply will be greatly appreciated !
Thanks. |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Wed May 12, 2004 1:37 pm |
|
|
The only registers you must save are the ones used in both main code and interupts. It can be dificult to determine exactly what registers are in use. You can look at the list file and see some of this. The indirect addressing registers are a good example. If you are accessing an array using an index in both main and in an interupt the indirect addressing registers need to be saved. This is really a shame because there are 3 sets of registers in the 18 series. If one set was used only in the interupts and it was the only set used in the interupts none of them would require saving. As the compiler is now only one set generally gets used. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu May 13, 2004 2:22 am |
|
|
I just finished a fast interrupt on a PIC18F458 and it's working great but there are some things to watch out for.
A couple of days ago I started the thread named: "Bug? Fast interrupts incompatible with option noclear?".
Many people gave me here helpful tips and examples for implementing fast interrupts.
Here a short summary:
1) Current versions of the compiler will allways add code for clearing the interrupt. The NOCLEAR parameter will be added to the oncomming v3.191.
2) Handling of multiple fast interrupts (e.g. EXT0 and EXT1) is not yet supported by the compiler. You can work around this by specifying one fast interrupt and write your own dispatcher in here. Remember from point 1 that the compiler will clear the interrupt for the known fast interrupt, the other interrupts you will have to clear yourself.
3) Compiler versions 3.188-3.190 contain a bug: Fast interrupts allways return with RETFIE 0 i.s.o RETFIE 1. This will be fixed in v3.191, for a workaround see the thread mentioned above.
4) Using C-code is possible, but you can never predict which registers the compiler is going to use. You can scan the .lst file for this, but the next compiler version might use different registers. See the generated code for the slow interrupt handler for which registers can be used. In my code I had to save the FSR0L, FSR0H and scratch-register3.
5) Older versions of the PIC18F452 had a hardware bug in the FAST interrupt, see the errata sheets and the afore mentioned thread. Although it has been fixed in the newer chips your supplier might find a cheap source of old stock.... |
|
|
prwatCCS
Joined: 10 Dec 2003 Posts: 70 Location: West Sussex, UK
|
|
Posted: Thu May 13, 2004 3:06 am |
|
|
ckielstra's pretty much said it all in his summary.
I was also one of the posters to the previous thread - do look there!
I have (with my workaround for v3.190 /RETFIE 1) sucessfully used FAST irq's with TIMER2, interrupting every 15us. I made no function calls within my fast irq handler (it's meant to be fast so calls just slow things down anyway) and inspected the list file carefully to see what had been generated. Again, I was interested in very fast code execution - after all at 15us interrupts you want to get out of the irq handler as fast as possible and leave some processor bandwith for other tasks and interrupts. My product has also to service incoming serial comms at 250KB, so I have low priority irqs every 44us as well as Timer0 providing an RTC every 10ms. All of this on an 18F6621 running at 40Mhz.
It is always worth looking at the code generated in irq handlers, as sometimes an elegant C construction results in more code than a more brute force approach. Code space on most of these 18F devices is plentiful.
So instead of "for loops", repeat the code explicitly for each case. Sure it may take up ROM space, but it will be faster, and is less likely to require the use of the FSR registers which you then have to save on enrty and exit ...
regards _________________ Peter Willis
Development Director
Howard Eaton Lighting Ltd UK |
|
|
|