title: dsPIC33EP512MU810 analogue comparator not working
body: <p>I'm having trouble getting the analogue comparator working on a dsPIC33EP512MU810. I want to compare two external voltages. Connected to C1IN1+ is my reference voltage (1.5V) and C1IN1- is my variable voltage (1.1 - 1.9V). I've set the Event trigger to be generated on both rising edge and falling edge but I only get an interrupt when the program starts and nothing after that. </p>
  
  <pre class="lang-c prettyprint-override"><code>// Macro to provide an indicator of when the ISR is running on a digital output pin (G6).
  #define MONIT_1 (LATGbits.LATG6)
  
  // Configuration registers.
  _FGS(GSSK_OFF);
  _FOSCSEL(FNOSC_PRIPLL &amp; IESO_ON);
  _FOSC(FCKSM_CSDCMD &amp; OSCIOFNC_OFF &amp; POSCMD_XT &amp; IOL1WAY_OFF);
  _FWDT(FWDTEN_OFF);
  _FPOR(BOREN_ON);
  _FICD(ICS_PGD2);
  _FAS(APLK_OFF);
  
  // The SYS_OSCSEL bits are written to the OSCCON.NOSC bits to select a new
  // oscillator and read from the OSCCON.COSC bits to determine the current
  // oscillator.
  #define SYS_OSCSEL      0b011       // 011 = Primary Oscillator with PLL (XTPLL, HSPLL, ECPLL)
  
  #define SYS_FIN         8000000LL   // clock-frequecy in Hz with suffix LL (64-bit-long)
  #define SYS_PLLPRE      0
  #define SYS_PLLPOST     1
  #define SYS_PLLDIV      38
  #define SYS_FVCO        ((SYS_FIN * (SYS_PLLDIV + 2)) / (SYS_PLLPRE + 2))
  #define SYS_FOSC        (SYS_FVCO / (2 * (SYS_PLLPOST + 1)))
  #define SYS_FCY         (SYS_FOSC/2)
  
  // bit 0 OSWEN: Oscillator Switch Enable bit
  #define OSCCON_OSWEN    (0x0001)  
  // bit 5 LOCK: PLL Lock Status bit (read-only)
  #define OSCCON_LOCK     (0x0020)    
  // bit 6 IOLOCK: Peripheral Pin Select (PPS) Lock bit
  #define OSCON_IOLOCK    (0x0040)   
  
  static volatile int _cout; // To capture the comparator output during the ISR.
  
  int main(int argc, char** argv) 
  {
       // Set up PLL to give Fosc = 40MHz from an 8MHz Crystal.
      CLKDIVbits.PLLPRE = SYS_PLLPRE;
      CLKDIVbits.PLLPOST = SYS_PLLPOST;
      PLLFBDbits.PLLDIV = SYS_PLLDIV;
  
      CLKDIVbits.DOZEN = 0;       // No Doze
      CLKDIVbits.ROI = 0;         // not setting recover on interrupt
  
      // Switch to PLL mode from XT.
      __builtin_write_OSCCONH(SYS_OSCSEL);
      __builtin_write_OSCCONL(OSCCON | 0x01);
      // Wait for Clock switch to occur
      while (OSCCON_OSWEN &amp; OSCCON);                  
      // Wait for PLL to lock
      while (OSCCONbits.LOCK != 1);                   
      // Wait for Oscillator to match
      while (OSCCONbits.COSC != OSCCONbits.NOSC);     
  
      // PIN20, C1IN1+ as analogue reference pin, VBUS -&gt; PL1.PIN20
      ANSELBbits.ANSB5 = 1;
      TRISBbits.TRISB5 = 1;
      // PIN11, C1IN1- as analogue voltage pin for VM1 -&gt; PL1.PIN11
      ANSELGbits.ANSG7 = 1;
      TRISGbits.TRISG7 = 1;
  
      // PIN10: digital MONIT_1 
      ANSELGbits.ANSG6 = 0;
      TRISGbits.TRISG6 = 0;
      MONIT_1 = 0;
  
      // Disable comparator
      CM1CONbits.CON = 0;
  
      // Continue operation in idle mode.
      CMSTATbits.CMSIDL = 0;
      // Comparator output is internal only
      CM1CONbits.COE = 0;
      // Comparator input is not inverted
      CM1CONbits.CPOL = 0;
      // Trigger/event/interrupt is generated on any change of the comparator output (while CEVT = 0)
      CM1CONbits.EVPOL = 0b11;
      // Comparator reference input selection. VIN+ input connects to external C1IN1+ pin
      CM1CONbits.CREF = 0;
      // Comparator channel selection. VIN- input connects to external C1IN1- pin
      CM1CONbits.CCH = 0b00;
  
      // Enable comparators
      CM1CONbits.CON = 1;
      // Enable comparator interrupts
      IEC1bits.CMIE = 1;
      // Enable the global interrupt
      INTCON2bits.GIE = 1;
      // Clear comparator interrupt flag
      IFS1bits.CMIF = 0;
  
      // Clear this value to enable future triggers and interrupts.
      CM1CONbits.CEVT = 0;
  
      while(1)
      {
          Nop();
      }
  
      return (EXIT_SUCCESS);
  }
  
  void __attribute__ ((__interrupt__,no_auto_psv)) _CM1Interrupt(void)
  {
      MONIT_1 = 1;        // Turn the G6 IO on.
  
      // Clear comparator interrupt flag
      IFS1bits.CMIF = 0;
  
      // Check if comparator event 1 occurred.
      if (CM1CONbits.CEVT &gt; 0)
      {
          _cout = CM1CONbits.COUT;
          // Clear comparator events to trigger the next event.
          CM1CONbits.CEVT = 0;
  
      }
      MONIT_1 = 0;        // Turn the G6 IO off.
  }
  </code></pre>