17.5.1 CVD Scan of Three Analog Inputs Using a Hardcoded Processing Sequence

In the following example, the ITC runs CVD on three analog inputs.

#include <xc.h>

// All pins CVD results.
long result[3]; 

int main(){

    PLL1CONbits.ON = 1;
    OSCCTRLbits.PLL1EN = 1;
    while(OSCCTRLbits.PLL1RDY == 0);   
    
    PLL1DIVbits.PLLFBDIV = 100; 		// VCO = 800 MHz
    PLL1DIVbits.PLLPRE = 1;
    PLL1DIVbits.POSTDIV1 = 4;
    PLL1DIVbits.POSTDIV2 = 1;
    PLL1CONbits.DIVSWEN = 1;
    while(PLL1CONbits.DIVSWEN == 1);    
    PLL1CONbits.NOSC = 1; // FRC
    PLL1CONbits.OSWEN = 1;
    while(PLL1CONbits.OSWEN == 1);        
    PLL1CONbits.FOUTSWEN = 1;
    while(PLL1CONbits.FOUTSWEN == 1);
    PLL1CONbits.PLLSWEN = 1;
    while(PLL1CONbits.PLLSWEN == 1);
    while(PLL1CONbits.CLKRDY == 0);


    // CPU clock 200MHz
    CLK1CONbits.ON = 1;
    CLK1CONbits.NOSC = 5; 			// PLL1
    CLK1CONbits.OSWEN = 1;
    while(CLK1CONbits.OSWEN == 1); 
    while(CLK1CONbits.CLKRDY == 0);
    
    // ADC (Generator 6) clock 200 MHz
    CLK6CONbits.ON = 1;
    CLK6CONbits.NOSC = 5; // PLL1
    CLK6CONbits.OSWEN = 1;
    while(CLK6CONbits.OSWEN == 1); 
    while(CLK6CONbits.CLKRDY == 0);

    // Initialize ADC 3 for operation with ITC
    AD3CH5CON1bits.MODE = 0; 		// single conversion
    AD3CH5CON1bits.IRQSEL = 0; 	     // each conversion interrupt
    AD3CH5CON1bits.PINSEL = 5; 	     // AD3AN5 is connected to CVD capacitors array
    AD3CH5CON1bits.NINSEL = 0; 	     // VSS
    AD3CH5CON1bits.SAMC = 0; 	       // small balance time
    AD3CH5CON1bits.TRG1SRC = 12; 	   // trigger for ITC
    AD3CONbits.ON = 1; 		      // enable ADC 3
    while (AD3ONbits.ADRDY == 0); 	  // wait for ready

    // List 0 will be processed by hardware sequence number 1 (CVD)
    ITCLS0SEQbits.DATASEQ = 1;
    // Each sequence will be executed 8 times per record
    ITCLS0SEQbits.ACCCNT = 8-1;
    ITCLS0SEQbits.ACCMODE = 1; 	    // back to back
    
    // Set CVD capacitor to 17.5 pF (maximum)
    ITCCON1bits.CVDEN = 1;
    ITCLS0SEQbits.CVDCAP = 7;
                
    // AN pins are grounded (LAT = 0) when idle
   TRISAbits.TRISA0 = 0; 		  //AN0
   TRISAbits.TRISA1 = 0; 	         //AN1
   TRISAbits.TRISA2 = 0; 	         //AN2
   
    // Assign AN pins to the records 
    ITCREC0bits.PIN0 = 0; 		// AN0 pin
    ITCREC0bits.PIN1 = 1; 		// AN1 pin
    ITCREC1bits.PIN2 = 2; 		// AN2 pin

    // Set timers for the acquisition sequences (A and B are used only)
    ITCLS0TMRbits.TMRA = 16; 	   // charge/discharge
    ITCLS0TMRbits.TMRB = 32; 	   // balance   

    // One trigger scans all records.
    // One interrupt is generated after scan
    ITCLS0CONbits.MODE = 5; 
    ITCLS0CONbits.WM = 0; 	    // always write to ITCRES registers
    ITCCON2bits.TMRPR = 0xffff;      // maximum period of internal timer
    ITCLS0CONbits.TRGSRC = 7; 	// internal timer trigger
    ITCLS0CONbits.RECCNT = 3;        // 3 records are in list 0
    ITCLS0CONbits.TRGEN = 1; 	// trigger enable
    ITCCON1bits.SIGN = 1; 	   // signed format is required for CVD
    ITCCON1bits.ON = 1; // enable ADC 2
    while(ITCSTATbits.DRDY == 0);

    while(1){ // scan in infinite loop        
        _ITCIF = 0; // clear ITC interrupt flag 
        while(_ITCIF == 0); 	// wait for the scan is done
        // store the results
        result[0] = ITCRES0;
        result[1] = ITCRES1;
        result[2] = ITCRES2;
    }
    return 1;
}