chipKIT® Development Platform

Inspired by Arduino™

Change Notification and PIC32MX250

Created Tue, 19 Nov 2013 16:43:08 +0000 by ChristopheDupriez


Tue, 19 Nov 2013 16:43:08 +0000


I have 3 Fubarinos Mini (PIC32MX250F128D) discussing using DigiMesh XBees, sleeping synchronously. I would like to have the Fubarinos sleeping when they have finished their chores but awakened when their XBee awake: the XBee "ON" (not SLEEP) pin is attached to one input pin of the Fubarino and I need now to manage CHANGE NOTIFICATIONS.

I have found this nice contribution from Majenko for the Uno: and I am wondering if I am right to try to adapt it for the PIC32MX250F128D or if a solution has already been developed?

I began to make changes to ChangeNotification (I attach the files) but it comes to more complicated register manipulations where I would be very happy to be helped a bit!



Current compilation errors of attached files: C:\Users\Christophe\Documents\mpide\libraries\ChangeNotification\ChangeNotification.cpp: In function 'void attachInterrupt(cn, void (*)(), unsigned char)': C:\Users\Christophe\Documents\mpide\libraries\ChangeNotification\ChangeNotification.cpp:61:2: error: 'CNEN' was not declared in this scope C:\Users\Christophe\Documents\mpide\libraries\ChangeNotification\ChangeNotification.cpp:64:11: error: 'volatile union __IFS1bits_t' has no member named 'CNIF' C:\Users\Christophe\Documents\mpide\libraries\ChangeNotification\ChangeNotification.cpp:65:11: error: 'volatile union __IEC1bits_t' has no member named 'CNIE' C:\Users\Christophe\Documents\mpide\libraries\ChangeNotification\ChangeNotification.cpp:66:11: error: 'volatile union __IPC6bits_t' has no member named 'CNIP' C:\Users\Christophe\Documents\mpide\libraries\ChangeNotification\ChangeNotification.cpp:67:11: error: 'volatile union __IPC6bits_t' has no member named 'CNIS' C:\Users\Christophe\Documents\mpide\libraries\ChangeNotification\ChangeNotification.cpp:68:2: error: 'CNCONbits' was not declared in this scope C:\Users\Christophe\Documents\mpide\libraries\ChangeNotification\ChangeNotification.cpp: In function 'void detachInterrupt(cn, char)': C:\Users\Christophe\Documents\mpide\libraries\ChangeNotification\ChangeNotification.cpp:97:4: error: 'CNEN' was not declared in this scope C:\Users\Christophe\Documents\mpide\libraries\ChangeNotification\ChangeNotification.cpp: In function 'void cn_isr()': C:\Users\Christophe\Documents\mpide\libraries\ChangeNotification\ChangeNotification.cpp:131:12: error: 'volatile union __IFS1bits_t' has no member named 'CNIF'


Tue, 19 Nov 2013 17:40:44 +0000

Change notification on the MX1/2 (and newer MX3/4) chips is implemented very differently to the other chips. It will take quite a few #ifdef blocks to get it working right on them. I wrote that library before I had ever had an MX1/2 chip to play with.

I will have a tinker and see what I can come up with.


Tue, 19 Nov 2013 18:10:19 +0000

This would be really nice, Matt! Thanks a lot!



Wed, 20 Nov 2013 00:26:14 +0000

Nope, it ain't gonna happen. The whole way I wrote that library is geared around how the old style CN works. I need to re-write it all in a better way really, referencing the digitalPinToCN[] array in the board definition (which didn't exist back when I wrote the library) and make it all work properly.

A slightly bigger job than I was hoping.


Wed, 20 Nov 2013 10:36:56 +0000

Looking at WInterrupts.c it seems to only support regular Interrupts (I may be better to use them then).

For digitalPinsToCN, it is a macro returning NOT_CN_PIN except for the UNO where it returns the content of table digital_pin_to_cn_PGM. Strange: this table is defined for the MAX too, but the macro digitalPinsToCN is not defined in MAX Boards_def.h.

Have a nice day!



Wed, 20 Nov 2013 10:43:07 +0000

Maybe you have an old version. That code was added to the MAX Board_Defs.h file quite recently.

It translates pin numbers into Change Notification bit numbers - it won't be used for the MX1/2 as the concept is meaningless - and needs manually adding for other boards (it's only on the Uno32 / Max32 at the moment).

Currently it's only used for dealing with the internal pull-up resistors of the IO ports.


Wed, 20 Nov 2013 11:04:16 +0000

My version is 2013/09/18.

For now, I will give a try to regular interrupts...

Have a nice afternoon,



Fri, 22 Nov 2013 21:46:59 +0000

Starting from code proposed in Microchip support forum: I modified it to try to make the simplest possible Change Notification test. Note that it works for PORTC (no specific pin) and must be adapted to your board. I hope it may help somebody:


Test Change Notification (CN) 


#include <plib.h>

volatile byte change = 0;

// -----------------------------------------------------------------------------
// Setup misc
// -----------------------------------------------------------------------------

void setup() {

  // Setup LED pins
  pinMode(PIN_LED1, OUTPUT);
  digitalWrite(PIN_LED1, LOW);

  // Disable analog functionality
  ANSELC = 0x0;
  // Set pin as input
  TRISCbits.TRISC4 = 0x1; // Same as pinMode(switchBit0, INPUT);
  TRISCbits.TRISC5 = 0x1; // Same as pinMode(switchBit0, INPUT);
  TRISCbits.TRISC6 = 0x1; // Same as pinMode(switchBit0, INPUT);
  TRISCbits.TRISC7 = 0x1; // Same as pinMode(switchBit0, INPUT);

  // Setup the change notice options
    #undef ON
  CNCONCbits.ON = 1;        //CN is enabled
  CNCONCbits.SIDL = 0;    //CPU Idle does not affect CN operation
  CNENCbits.CNIEC4 = 1;    //Enable RC4 change notice
  CNENCbits.CNIEC5 = 1;    //Enable RC5 change notice
  CNENCbits.CNIEC6 = 1;    //Enable RC6 change notice
  CNENCbits.CNIEC7 = 1;    //Enable RC7 change notice
  // Read port C to clear mismatch condition
  int tmp = PORTC;

  // Clear CN interrupt flag, set CN interrupt priority, enable CN interrupt
  IFS1bits.CNCIF = 0;           // clear status register for port C
  IPC8CLR = _IPC8_CNIP_MASK;                //clear priority
  IPC8SET = (2 << _IPC8_CNIP_POSITION);    //set priority (2)
  IEC1bits.CNCIE = 1; // enable CN interrupts on port C

  // Pulldown enable
  CNPDCbits.CNPDC4 = 0;
  CNPDCbits.CNPDC5 = 0;
  CNPDCbits.CNPDC6 = 0;
  CNPDCbits.CNPDC7 = 0;

  // Enable interrupts
  //   INTEnableSystemMultiVectoredInt();  ALREADY DONE


// -----------------------------------------------------------------------------
// Main
// -----------------------------------------------------------------------------

void loop() {
  change = 0;

void blink(int times)
  if (times == 0) return;
  int i;
  for (i = 0; i < times - 1; i++)
    digitalWrite(PIN_LED1, HIGH);
    digitalWrite(PIN_LED1, LOW);
#ifdef __cplusplus
extern "C" {

// Declare interrupt handler
void ChangeNotice(void) __attribute__ ((interrupt));  

// -----------------------------------------------------------------------------
//  ISR handlers
// -----------------------------------------------------------------------------

// Implement interrupt handlers
void __ISR(_CHANGE_NOTICE_VECTOR, ipl2) ChangeNotice_Handler(void)
  // Read the port (automatically clears the state)
  change = ( PORTC ? true : true );

  // Clear the interrupt flag
  IFS1bits.CNCIF = 0;

#ifdef __cplusplus