28.5.2.1 Interleaved Sampling Step Command Program

This section describes the step command programming for implementing the timing sequence shown in Figure 28-11.

The following assumptions are made:
  1. Trigger Input 0 is connected to the PWM1 signal. The rising edge of this signal starts the sequence. PWM1 has a period of 50us.
  2. Output Trigger 12 is connected to the ADC module. This signal gives command to the ADC module to begin a sample and conversion process.
  3. Interrupt 0 is used to indicate to the processor that a subsequence has started (provides status).
  4. Interrupt 1 is used to indicate to the processor that the entire sequence has completed.
  5. The PTG clock source is 125 MHz.
  6. The initial trigger delay is 5 μs.
  7. The second trigger delay is 6 μs.
  8. In each PWM cycle, the ADC will be triggered 25 times.
  9. The basic sequence is executed twice.

Interleaved Sampling Step Command Program

#include <xc.h>

//Allocate buffers for ADC results. 
//Size of 50 is based on 2 PWM cycles, 25 results per cycle.
#define RESULT_BUFFER_SIZE 50
unsigned int voltage_buffer[RESULT_BUFFER_SIZE];
int voltage_buffer_index = 0;
unsigned int current_buffer[RESULT_BUFFER_SIZE];
int current_buffer_index = 0;
_Bool readings_ready = 0;

void clocks_initialize() {
    //Set up CPU clock (Fcy) to run at 200 MHz. 

    //Start by configuring PLL1
    
    PLL1CONbits.ON = 1; //Enable PLL1, if not already enabled
    
    //PLL1 has input frequency 8MHz (FRC)
    PLL1DIVbits.PLLPRE = 1;         //Reference input will be 8MHz, no division
    PLL1DIVbits.PLLFBDIV = 125;     //Fvco = 8MHz * 125 = 1000MHz
    PLL1DIVbits.POSTDIV1 = 5;       //Divide Fcvo by 5
    PLL1DIVbits.POSTDIV2 = 1;       //Fpllo = Fvco / 5 / 1 = 200 MHz

    //The PLLSWEN bit controls changes to the PLL feedback divider.
    //Request PLL1 feedback divider switch
    PLL1CONbits.PLLSWEN = 1;
    //Wait for PLL1 feedback divider switch to complete
    while(PLL1CONbits.PLLSWEN);

    //The FOUTSWEN bit controls changes to the PLL output dividers.
    //Request PLL1 output divider switch
    PLL1CONbits.FOUTSWEN = 1;
    //Wait for PLL1 output divider switch to complete
    while(PLL1CONbits.FOUTSWEN);
    
    VCO1DIVbits.INTDIV = 2; //Divide Fvco by 4
    //The DIVSWEN bit controls changes to the VCO divider.
    //Request PLL1 VCO divider switch
    PLL1CONbits.DIVSWEN = 1;
    //Wait for PLL1 VCO divider switch to complete
    while(PLL1CONbits.DIVSWEN);

    //Reset CLKGEN1 dividers for 1:1 ratio
    CLK1DIVbits.INTDIV = 0;
    CLK1DIVbits.FRACDIV = 0;
    //Request CLKGEN1 divider switch
    CLK1CONbits.DIVSWEN = 1;
    //Wait for divider switch to complete
    while(CLK1CONbits.DIVSWEN);
    
    CLK1CONbits.NOSC = 5;       //Set PLL1 Fout as CPU clock source
    CLK1CONbits.OSWEN = 1;      //Request clock switch
    while (CLK1CONbits.OSWEN);  //Wait for switch to complete

    
    //Configure CLKGEN5 to provide a 125MHz PWM MCLK

    CLK5CONbits.ON = 1; //Enable CLKGEN5, if not already enabled
    
    CLK5DIVbits.INTDIV = 1; //Divide input clock by 2
    CLK5DIVbits.FRACDIV = 0;
    //Request CLKGEN5 divider switch
    CLK5CONbits.DIVSWEN = 1;
    //Wait for CLKGEN5 divider switch to complete
    while(CLK5CONbits.DIVSWEN);

    CLK5CONbits.NOSC = 7;       //Use divided PLL1 VCO (250MHz)
    CLK5CONbits.OSWEN = 1;      //Request clock switch
    while(CLK5CONbits.OSWEN);   //Wait for switch to complete
    
    PCLKCONbits.MCLKSEL = 1;    //Use CLKGEN5 as PWM MCLK source

    
    //Configure CLKGEN6 to provide a 250MHz input clock to the ADC

    CLK6CONbits.ON = 1; //Enable CLKGEN6, if not already enabled
    
    //Reset CLKGEN6 dividers for 1:1 ratio
    CLK6DIVbits.INTDIV = 0;
    CLK6DIVbits.FRACDIV = 0;
    //Request CLKGEN6 divider switch
    CLK6CONbits.DIVSWEN = 1;
    //Wait for CLKGEN6 divider switch to complete
    while(CLK6CONbits.DIVSWEN);
    
    CLK6CONbits.NOSC = 7;       //Use divided PLL1 VCO (250MHz)
    CLK6CONbits.OSWEN = 1;      //Request clock switch
    while (CLK6CONbits.OSWEN);  //Wait for switch to complete

    
    //Configure CLKGEN11 to provide a 125MHz clock for the PTG.

    CLK11CONbits.ON = 1; //Enable CLKGEN10, if not already enabled
    
    CLK11DIVbits.INTDIV = 1; //Divide input clock by 2
    CLK11DIVbits.FRACDIV = 0;
    //Request CLKGEN11 divider switch
    CLK11CONbits.DIVSWEN = 1;
    //Wait for CLKGEN11 divider switch to complete
    while(CLK11CONbits.DIVSWEN);

    CLK11CONbits.NOSC = 7;      //Use divided PLL1 VCO (125MHz)
    CLK11CONbits.OSWEN = 1;     //Request clock switch
    while (CLK11CONbits.OSWEN); //Wait for switch to complete
}

void PTG_initialize() {
 
    //Enable PTG interrupts 0 and 1
    _PTG0IE = 1;
    _PTG1IE = 1;

    //Set up control registers
    PTGT0LIM = 625;     //5us T0 delay
    PTGT1LIM = 125;     //1us T1 delay
    PTGC0LIM = 24;      //Repeat C0 loop 25 times
    PTGC1LIM = 1;       //Repeat C1 loop once
    PTGHOLD = 625;      //5us (used to restore T0 delay)
    PTGADJ = 125;       //1us (added to T0 delay)
    PTGQPTR = 0;        //Initialize step queue pointer

    //Outer loop
    PTGQUE0bits.STEP0 = PTGWHI(0);       // Wait for positive edge trigger 0 (PWM1 ADC Trigger 2)
    PTGQUE0bits.STEP1 = PTGCTRL(t0Wait); // Start PTGT0, wait for time out
    PTGQUE0bits.STEP2 = PTGIRQ(0);       // Generate IRQ 0
    // Inner loop
    PTGQUE0bits.STEP3 = PTGTRIG(12);     // Generate output trigger 12 (ADC conversion)
    PTGQUE1bits.STEP4 = PTGCTRL(t1Wait); // Start PTGT1, wait for time out
    PTGQUE1bits.STEP5 = PTGJMPC0(3); // Go to STEP3 if PTGC0 != PTGC0LIM, increment PTGC0 (ie. repeat steps 3-5 24 times)
    // End inner loop
    PTGQUE1bits.STEP6 = PTGADD(t0Limit); // Add PTGADJ to PTGT0LIM
    PTGQUE1bits.STEP7 = PTGJMPC1(0);     // Jump to 0 PTGC1LIM times (once, making 2 iterations)
    // End outer loop

    PTGQUE2bits.STEP8 = PTGIRQ(1);      // Generate IRQ 1
    PTGQUE2bits.STEP9 = PTGCOPY(t0Limit);

See PTG Command Definitions for PTG command definitions. See PTGCTRL Options and Options for PTGADD and PTGCOPY Commands for PTGCTRL, PTGADD and PTGCOPY command options.