How to add an ISR when already using ISRRX

Coding and general discussion relating to user created compiler modules

Moderators: David Barker, Jerry Messina

Post Reply
TonyR
Posts: 75
Joined: Fri Jan 14, 2011 11:49 pm
Location: Sydney
Contact:

How to add an ISR when already using ISRRX

Post by TonyR » Mon Mar 31, 2014 12:56 am

Good Morning (it is here!)

I have a SF module working well using the ISRRX module for serial comms. in an 18F87J50.

I need to add an ISR that blinks a LED on a pin when Vcc falls past half (ie. 1.7V).

The comparator and ISR (called GSMoff) work nicely on their own, but when I add it to the code with ISRRX installed I get a compiler at my line "enable(GSMoff)" saying "interrupt vector in use".

This is to be expected I assume, because ISRRX is already using the interrupt system.

But how to I add another .... I've read everywhere and tried a lot of ways but no good. Anyone with advice - most welcome !!!

This is the ISR, really simple

Code: Select all

Interrupt GPSoff()
  PIR2.6 = 0
  Save(0)
  High(PORTE.1)
  DelayMS(100)
  Low(PORTE.1)
  DelayMS(100)
  Restore  
End Interrupt
This is the comparator and interrupt setup

Code: Select all

CVRCON = %10101100       ' Setup internal Vref: turn on, no ext o/p, use vdd as ref, set v to 1.23
CM2CON = %10001100       ' Setup comparator 2: turn on, no ext o/p, interrupt on H, use internal Vref, take input signal from pin 18  AN7

INTCON = %11000000       ' enable global interrupts
PIR2.6 = 0               ' clear comparator 2 interrupt flag
PIE2.6 = 1               ' enable comparator 2 interrupt
This is the line that causes compiler error

Code: Select all

enable(GSMoff)

User avatar
RangerBob
Posts: 152
Joined: Thu May 31, 2007 8:52 am
Location: Beds, UK

Re: How to add an ISR when already using ISRRX

Post by RangerBob » Mon Mar 31, 2014 1:20 pm

The Easiest way would probably to use the High/Low interrupt vectors that these devices support. Put one interrupt to high, the other to low. Bear in mind that the low priority can/will be interrupted itself by the high, but for serial comms, you can probably put the ISRRX onto the low as there is some hardware buffering. Have a look at "Handling Interrupts" in the help file for details but the guts of it are:

Code: Select all

const
   ipLow = 1,
   ipHigh = 2

interrupt OnTimer1(ipLow)
   // code statements here…
end interrupt

interrupt OnTimer3(ipHigh)
   // code statements here…
end interrupt
Otherwise you can start manually merging the interrupt codes. Then when an interrupt fires, you'll have to check which ISR flag fired, and branch to the appropriate handler, but thats a lot of work!

Jerry Messina
Swordfish Developer
Posts: 1237
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: How to add an ISR when already using ISRRX

Post by Jerry Messina » Mon Mar 31, 2014 2:20 pm

Just to add a bit to what RangerBob said...

Since all peripherals default to using the high-priority ISR, when using high/low interrupt priorities you'll also need to setup the IPR bit for the peripheral that you want to assign to the low-priority ISR. For comparator 2 that's the CM2IP (bit 6) in IPR2 register.

I'd suggest that you leave ISRRX assigned to the high-priority intr and setup the comparator for ipLow. You have some VERY long delays in the GPSoff() routine. If you set GPSoff() to ipHigh, then it'll block your low priority intr for 200ms while the led blinks. That would likely cause your serial ISR to fail.

In general you'd be better off removing the delayms() calls from the ISR. Handle what you need to do immediately in the ISR, and set a flag for the main loop to finish things up later, maybe something like

Code: Select all

dim
	CM2IF as PIR2.6,
	CM2IP as IPR2.6
	
dim GPSactive as boolean      // flag to indicate a CM2 intr has occurred 

Interrupt GPSoff(ipLow)
  CM2IF = 0
  High(PORTE.1)			// want this to occur when the ISR triggers
  GPSactive = true		// indicate to main loop that we've seen a CM2 intr
End Interrupt

main:
	GPSactive = false
	
	// do your comparator setup code, and make sure CM2IP = 0 for ipLow
	
	while (true)
	...
		if (GPSactive) then		// we got a comparator intr
			GPSactive = false	
			delayms(100)
  		 Low(PORTE.1)
			delayms(100)		// this isn't really needed...		
		endif
	end while
Some other notes:

You can remove the 'INTCON = %11000000' statement from your code... that'll be managed by the compiler when it sees you're using ipHigh/ipLow.
enable(GSMoff)
I assume here you mean 'enable(GPSoff)'

TonyR
Posts: 75
Joined: Fri Jan 14, 2011 11:49 pm
Location: Sydney
Contact:

Re: How to add an ISR when already using ISRRX

Post by TonyR » Mon Mar 31, 2014 4:36 pm

Thanks greatly for your suggestions Bob and Jerry.

You are right about the long delay blocking things, actually this ISR only gets called at power down so its not so important.

By trial and error I set isrrx to IPlow with a #option statement at the top of my program then magically the error on my "enable(GSMoff)" statement disappeared.

At this point all seems to work perfectly - my comms happily reads and writes data at 115K and the ISR when called works and returns to the main program and nothing crashes.

I don't really know why but I'm happy!!

TonyR
Posts: 75
Joined: Fri Jan 14, 2011 11:49 pm
Location: Sydney
Contact:

Re: How to add an ISR when already using ISRRX

Post by TonyR » Mon Mar 31, 2014 4:38 pm

Sorry, should have written enable(GPSoff) !

Post Reply