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

PIC24 'Interrupt-on-change Notification' problem

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



Joined: 30 Jun 2011
Posts: 21
Location: King's Lynn. England

View user's profile Send private message

PIC24 'Interrupt-on-change Notification' problem
PostPosted: Sat Jul 06, 2013 7:57 am     Reply with quote

Compiler : V5.008
PIC24FJ256GA106

Hi everyone, I am trying to use the 'Interrupt-on-change Notification' to wake up an instrument using two port pins.
The problem is, that I can wake the instrument up from either port pin , but when I combine them the compiler doesn't like it. Can anyone please tell me what I'm doing wrong, as I'm having a hard time figuring this one!

example code
Code:
#define  ON_OFF      PIN_D9
#define  POWERGOOD   PIN_F3

enable_interrupts(INTR_CN_PIN|ON_OFF);           // This works OK
enable_interrupts(INTR_CN_PIN| POWERGOOD);       // So does this
enable_interrupts(INTR_CN_PIN|ON_OFF|POWERGOOD); // Error

#INT_CNI
void  cni_isr(void)
{
   if(!input(ON_OFF))
   {
      // Do something
   }
   if (input(POWERGOOD))
   {
      // Do something
   }
}

Thanks in advance
jeremiah



Joined: 20 Jul 2010
Posts: 1327

View user's profile Send private message

PostPosted: Sat Jul 06, 2013 8:21 am     Reply with quote

I've always done them individually. I don't think you can combine them into one statement. Doing them individually will still turn them all on. On change interrupts change an additional register which you can verify in the LST file. For example, I am using 4 on change interrupts on a current project and individually setting them works such that all 4 trigger the interrupt.
NWilson



Joined: 30 Jun 2011
Posts: 21
Location: King's Lynn. England

View user's profile Send private message

PostPosted: Sat Jul 06, 2013 8:46 am     Reply with quote

Hi jeremiah,
Thanks for the quick reply,

Still a little confused! do you mean that I've nearly got it right, I just enable the interrupts separately and have one interrupt handler or do I have to have separate interrupt handlers for each pin?

I.E.

Code:
#define  ON_OFF      PIN_D9
 #define  POWERGOOD   PIN_F3

 enable_interrupts(INTR_CN_PIN|ON_OFF);           // Enable each pin separately
 enable_interrupts(INTR_CN_PIN| POWERGOOD);
 enable_interrupts(INTR_GLOBAL);
 
 #INT_CNI
 void  cni_isr(void)
 {
    if(!input(ON_OFF))
    {
       // Do something
    }
    if (input(POWERGOOD))
    {
       // Do something
    }
 }


If you've got an example that would be great.
Regards
Neil
jeremiah



Joined: 20 Jul 2010
Posts: 1327

View user's profile Send private message

PostPosted: Sat Jul 06, 2013 9:09 am     Reply with quote

What you have there will work.


Just be careful how you handle the ISR as all rising and falling edge transitions on each of your inputs will cause the whole ISR to trigger. It's a little extra processing, but I like to check and see what the previous I/O state was in addition to the current state to ensure it was an edge transition for that particular I/O. Also, if any of your inputs for the interrupt are from a button or switch type input, you may have to also consider debouncing, depending on the application.
NWilson



Joined: 30 Jun 2011
Posts: 21
Location: King's Lynn. England

View user's profile Send private message

PostPosted: Sat Jul 06, 2013 9:18 am     Reply with quote

Cheers Jeremiah
The code in the ISR de-bounces a switch and checks when the battery is charging, so is a little bit more complicated than that shown.
I didn't think to enable them separately, but will give it a go when I get back to work on Monday.

Regards
Neil
Ttelmah



Joined: 11 Mar 2010
Posts: 19350

View user's profile Send private message

PostPosted: Sat Jul 06, 2013 11:48 am     Reply with quote

It is somewhat confusing.
The Interrupt on Change, is the one form of interrupt where you 'OR' things in. There is a 'remark' in the include file which says something like 'OR with a define' (note the 'a'). What seems to happen is that it calculates back from the pin number, to generate the bit in the mask register, but doesn't handle multiple bits in one instruction. It would be impossible to do from multiple 'ored' values, since if you 'or two pin defines, you get another pin. However if you do it twice, and check what is generated, it merrily sets multiple bits.
It's a non documented limitation of the way the compiler does things.
Yes there is only one actual 'CNI' interrupt.

Best Wishes
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sun Jul 07, 2013 2:08 am     Reply with quote

I must confess that I never became aware of the problem because I enabled change notification of individual
bits by writing to the CNENx registers.
Ttelmah



Joined: 11 Mar 2010
Posts: 19350

View user's profile Send private message

PostPosted: Sun Jul 07, 2013 3:34 am     Reply with quote

Agreed

What goes wrong, is inherent in the way that CCS defines pin names. So (for instance), PIN_B0 is 5696, B1 5697, B2 5698 etc.. If you 'or' B0, with B1, you get the number for B1, while if you or B1, with D0 (5697, with 5792), you get 5857, which is not a legitimate pin number, and hence the 'error'.

What is 'silly' is that they should have either defined masks for this function (called something like CNEN_B0 for example), which could then directly be masks, and therefore could be ore'd together, or have thoroughly documented the limitation of the current approach.....

They are trying to be a little too 'smart', by using the existing pin names.

Best Wishes
NWilson



Joined: 30 Jun 2011
Posts: 21
Location: King's Lynn. England

View user's profile Send private message

PostPosted: Sun Jul 07, 2013 4:07 am     Reply with quote

Hi Ttelmah / FvM,

Many thanks for clearing that up for me. I must admit that after your reply yesterday I did some 'Or' ing and couldn't possibly see how
Code:
enable_interrupts(INTR_CN_PIN|ON_OFF|POWERGOOD);

could work.
As for writing directly to the CNENx registers, as FvM does, I'd rather let the compiler deal with things like that as I'm a relatively inexperienced programmer.
Hopefully I will get it going tomorrow.
Regards
Neil
jeremiah



Joined: 20 Jul 2010
Posts: 1327

View user's profile Send private message

PostPosted: Sun Jul 07, 2013 7:35 am     Reply with quote

One thing to watch out for is you are using the new compiler which is still very new. I have something similar to what you posted in your last example working in 3 different projects, but on the 4.xxx compiler version. If it doesn't work, check the LST output of the 5.xxx compiler and make sure the calls to enable_interrupts are doing 2 things: 1.) Turning on the CNI interrupt and 2.) changing the CNENx registers (if I remember correctly, it is a bit set instruction).

You are right in that you shouldn't need to directly address the CNENx register at all.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sun Jul 07, 2013 8:21 am     Reply with quote

I'm not against CCS built-in functions, they are convenient and mostly do what they claim to do. But sometimes
you need to go down to the SFR level to achieve a specific function, either because the built-in function has
errors or cant' do something by design. With CNI enable it's the latter case, unfortunately the manual doesn't mention
the restriction of only enabling a single pin per function call.

To use CNENx SFR, you must know the CNx bit number associated to a pin, then set the respective bit in CNENx register. Consequently, CNIE0 to CNIE15 are in CNEN1, CNIE16 to CNIE31 in CNEN2 etc.

You can use #bit to define individual CNIEx bits and #word to define the CNENx registers.
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