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.ACCNUM = 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   
    
    ITCCON2bits.CLKSEL = 1; // Clock from Generator 6 (200MHz)
    ITCCON2bits.CLKDIV = 4; // Divide by 8 to get 25 MHz ADC clock

    // 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;
}