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 CCS Technical Support

Fast interrupt dispatcher

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



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

Fast interrupt dispatcher
PostPosted: Wed Jun 02, 2004 10:36 am     Reply with quote

Does anyone have an example of low priority and high priority interrupts working together?

My code has a 100uS TIMER0 interrupt and I want a fast EXT and RDA interrupts. EXT is just a VarA=VarB and RDA is a buffer[index++]=rcreg and code to build a linear buffer.

The problem is the lack of knowloedge to write a fast interrupt dispatcher.
ckielstra



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

View user's profile Send private message

PostPosted: Wed Jun 02, 2004 1:03 pm     Reply with quote

Which processor and compiler version are you intending to use?

Two problems in v3.188 were promised to be fixed in 3.191, but the problems are not mentioned in the list of changes and I haven't tested any of the newer compiler versions yet.

I can recommend you to read http://www.ccsinfo.com/forum/viewtopic.php?t=19286
Guest








PostPosted: Wed Jun 02, 2004 1:13 pm     Reply with quote

PIC18F452 and 3.187, clock at 40mhz
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Wed Jun 02, 2004 1:21 pm     Reply with quote

This guest thing should be disabled ;)

The code is already working, but only EXT is a fast interrupt.

I think it is bad to pass through almost 150 instructions just to receive a byte.
Gerrit



Joined: 15 Sep 2003
Posts: 58

View user's profile Send private message

PostPosted: Wed Jun 02, 2004 2:47 pm     Reply with quote

If you alrady have an 100 us interupt just check for rda buffer and read as nessesery.

If you handle two interupts in fast int you also have to check what int it
was so why no check for char received.

You can handle +- 100 kBit serial stream.


Gerrit
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Wed Jun 02, 2004 3:15 pm     Reply with quote

A question comes to my mind.

If I set global int and do not enable interrupt for RDA, the receive interrupt flag is set to 1 when a byte is received?
ckielstra



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

View user's profile Send private message

PostPosted: Wed Jun 02, 2004 3:52 pm     Reply with quote

V3.187 is a good version for fiddling with the fast interrupts, and I guess you have read the PIC18F452 errata sheets by now?

Implementing one fast interrupt in the CCS compiler is relatively easy as you have already figured out, but implementing multiple fast interrupts requires some tweaking.

This is how I did it:
1) The Status, Wreg and BSR registers are automatically saved in a Fast interrupt, but the other registers you will have to save yourself. This is a good reason for writing your interrupt handler in assembly because a new compiler version might use different registers.... If you do want to mix C and assembly (like I did) then double check your code for using the scratch registers on address 1 to 4. I forgot to save one register and this caused all kind of strange problems.
2) For the first Fast interrupt (int_ext in my example) you have to do nothing, the priority is automatically set by the compiler and the interrupt is cleared on exit. But for the other interrupt you will have to code these two actions yourself, this requires a bit working around the compiler.

Code:

#define intcon  0xFF2     
#define intcon2 0xFF1     
// etc

int8 save_fsr0l;
int8 save_fsr0h;
int8 save_scratch3;

void init()
{
  // Setup timer2
  Setup_Timer_2(T2_DIV_BY_1, EXTSER_BIT_TIME - 1, 1);
  IPR1bits.TMR2IP = 1;      // Make this a high priority interrupt
                            // The CCS compiler has no method for
                            // specifying multiple High Priority interrupts.
  // enable_interrupts(INT_TIMER2);  // Do not enable, or compiler
                                     // will add a low priority handler

  // Setup RS-232 receive pin (Ext0)
  ext_int_edge(0, H_TO_L);    // Interrupt on fallling edge
  enable_interrupts(INT_EXT);
}

#INT_EXT FAST
void fast_isr()
{
  // Save registers
#ASM
  movff   FSR0L, save_fsr0l
  movff   FSR0H, save_fsr0h
  movff   3, save_scratch3    // used by some C-code I'm calling

  // Determine which interrupt source is active
  btfss   intcon,intf     ; external interrupt?
  goto    intovfl         ; no, go     
  bcf     intcon,intf     ; yes. Clear external interrupt flag
                          ; note: not required, compiler adds code at exit
  ; Do some more stuff here.

intovfl:
  btfss   pir1,t2if       ; timer overflow?
  goto    int_exit        ; no, go exit
  bcf     pir1,t2if       ; clear timer interrupt
                          ; note: This clear is required, compiler will not do it.
  ; Do some more stuff here.
 
int_exit:
  // Restore registers
  movff   save_fsr0l, FSR0L
  movff   save_fsr0h, FSR0H
  movff   save_scratch3, 3
#ENDASM
}
Ttelmah
Guest







Re: Fast interrupt dispatcher
PostPosted: Thu Jun 03, 2004 2:17 am     Reply with quote

future wrote:
Does anyone have an example of low priority and high priority interrupts working together?

My code has a 100uS TIMER0 interrupt and I want a fast EXT and RDA interrupts. EXT is just a VarA=VarB and RDA is a buffer[index++]=rcreg and code to build a linear buffer.

The problem is the lack of knowloedge to write a fast interrupt dispatcher.

As others have said, I'd probably handle the RDA interrupt another way. The 'fastest' response, to INT EXT, would be to just code this using FAST, then simply copy the bytes (which only needs affect the W reg, and the BSR), and use the RETFIE 1 ability to restore these registers. The 'key' problem at each level, is how many registers have to be saved. Using an array in the RDA handler, implies that several of the table pointer registers, and a couple of scratch registers have to be saved. You can look through the assembler listing of each routine you intend to use in each interrupt, and get a list of the registers that are used. You may also consider reducing the interrupt overhead on the low priority interrupt by taking advantage of this information (especially given that your system is going to be spending a large percentage of it's time in the 100uSec timer interrupt). So (for instance), if you know that this is the only low priority interrupt in use, and hence that if the handler is called, this interrupt must have happened, you can remove the code to check which interrupt has occurred, and that the interrupt is enabled. In answer to another question you have raised, yes the RDA interrupt flag is set even if the interrupt is disabled. So if you code a int_global handler to only save the registers needed by the RDA, and timer tick routines, then do the timer handling (given that this is the only low priority interrupt), clear the timer interrupt flag, check if RDA is set, save the data, and clear this flag if so, restore the registers, and exit, I'd expect to be able to reduce the overhead by perhaps 30-40% on the low priority interrupt, giving a fairly effective result.
I have posted in the past example 'int_global' code for this type of approach.
Big caveat, are you sure that you have late enough chips, that you are not going to be affected by the asynchronous fast interrupt errata?...

Best Wishes
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Thu Jun 03, 2004 4:15 am     Reply with quote

This is a good question, the chip is a PIC18F452-I/P 0412262.
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