28.5.3.1 Ratioed Sampling Step Command Program

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

The following assumptions are made:
  • Trigger Input 15 is connected to the zero-crossing detect. The rising edge of the Zero-Crossing Detect signal starts the sequence.
  • Trigger Output 24 enables the SCR in the application circuit.
  • The trigger delay from Trigger Input 15 to the generation of Trigger Output 24 is 2 ms.
  • Trigger Output 26 is connected to PWM1’s synchronization signal.
  • PWM1 is configured to trigger the ADC to sample at 1/2x rate, and it is configured to trigger PWM2 which will sample the ADC at 1x rate.
  • Trigger Output 12 is connected to the ADC to sample other data values (channels 0, 1, 2, an 3) once per cycle.
  • The PTG clock is 8 MHz.

Ratioed Sampling Step Command Program

#include <xc.h>

void clocks_initialize() {
    
    //Configure CLKGEN5 to provide an 8MHz clock for the PWM
    CLK5CONbits.ON = 1;             //Enable CLKGEN5, if not already enabled
    
    //Reset CLKGEN5 dividers for 1:1 ratio
    CLK5DIVbits.INTDIV = 0;
    CLK5DIVbits.FRACDIV = 0;
    CLK5CONbits.DIVSWEN = 1;
    //Wait for divider switch to complete
    while(CLK5CONbits.DIVSWEN);

    CLK5CONbits.NOSC = 1;           //Select FRC, 8MHz
    CLK5CONbits.OSWEN = 1;          //Request clock switch
    while (CLK5CONbits.OSWEN);      //Wait for switch to complete
    
    PCLKCONbits.MCLKSEL = 1;        //Use CLKGEN5 for PWM clock
    
    
    PLL1CONbits.ON = 1; //Enable PLL generator 1, if not already enabled

    //Set up PLL1
    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;
    CLK1CONbits.DIVSWEN = 1;
    //Wait for divider switch to complete
    while(CLK1CONbits.DIVSWEN);
    
    CLK1CONbits.NOSC = 1;       //Set FRC as CPU clock source
    CLK1CONbits.OSWEN = 1;      //Request clock switch
    while (CLK1CONbits.OSWEN);  //Wait for switch to complete

    //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;
    CLK6CONbits.DIVSWEN = 1;
    //Wait for divider switch to complete
    while(CLK6CONbits.DIVSWEN);
    
    CLK6CONbits.NOSC = 7;       //Set PLL1 VCODIV as ADC clock source
    CLK6CONbits.OSWEN = 1;      //Request clock switch
    while (CLK6CONbits.OSWEN);  //Wait for switch to complete

    //Configure CLKGEN11 to provide an 8MHz clock for the PTG
    
    CLK11CONbits.ON = 1; //Enable CLKGEN10, if not already enabled
    
    //Reset CLKGEN11 dividers for 1:1 ratio
    CLK11DIVbits.INTDIV = 0;
    CLK11DIVbits.FRACDIV = 0;
    //Request CLKGEN11 divider switch
    CLK11CONbits.DIVSWEN = 1;
    //Wait for divider switch to complete
    while(CLK11CONbits.DIVSWEN);

    CLK11CONbits.NOSC = 1;      //Select FRC, 8MHz
    CLK11CONbits.OSWEN = 1;     //Request clock switch
    while (CLK11CONbits.OSWEN); //Wait for switch to complete
}

void PTG_initialize() {
 
    PTGT0LIM = 16000; // 2 ms T0 delay
    PTGT1LIM = 8000;  // 1 ms T1 delay
    PTGC0LIM = 2;     // 3 iterations of the C0 loop

    PTGQPTR = 0; //Initialize step queue pointer
    
    //Initialize Step registers
    PTGQUE0bits.STEP0 = PTGWHI(15);        // Wait for trigger from INT2 (zero crossing detect)
    PTGQUE0bits.STEP1 = PTGTRIG(12);       // Take 1/8 rate samples using ADC trigger 30
    PTGQUE0bits.STEP2 = PTGCTRL(t0Wait);   // Wait 2ms
    PTGQUE0bits.STEP3 = PTGTRIG(24);       // Trigger PPS output 55 (SCR)
    PTGQUE1bits.STEP4 = PTGCTRL(t1Wait);   // Wait1ms before starting the 1x and 1/2x triggers
    PTGQUE1bits.STEP5 = PTGTRIG(26);       // Trigger PWM1 to trigger conversions at 1x and 1/2x rates
    //Start main loop
    PTGQUE1bits.STEP6 = PTGCTRL(t0Wait);   // Wait2ms (pre-trigger delay) for subsequent triggers
    PTGQUE1bits.STEP7 = PTGTRIG(26);       // Trigger PWM1 to trigger ADC conversions at 1x and 1/2x rates
    PTGQUE2bits.STEP8 = PTGJMPC0(6);       // Jump to step 6 (twice, for 3 iterations total)
    //End main loop
    PTGQUE2bits.STEP9 = PTGJMP(0);

    //Start the PTG
    PTGCONbits.ON = 1;
    PTGCONbits.PTGSTRT = 1;
}

void ADC_initialize() {
 
    //Enable analog inputs AD1AN0 - AD1AN5
    _ANSELA2 = 1;
    _ANSELA4 = 1;

    _ANSELA6 = 1;
    _ANSELA5 = 1;
    _ANSELB1 = 1;
    _ANSELB3 = 1;

    //Enable ADC
    AD1CONbits.ON = 1;
    while(!AD1CONbits.ADRDY);

    //Assign ADC inputs to core 1 channels 0 - 5
    AD1CH0CON1bits.MODE = 0;   //Single-sample mode
    AD1CH0CON1bits.PINSEL = 0; //Positive input is AD1AN0/RA2
    AD1CH0CON1bits.NINSEL = 0; //Single-ended mode

    AD1CH1CON1bits.MODE = 0;   //Single-sample mode
    AD1CH1CON1bits.PINSEL = 1; //Positive input is AD1AN1/RA4
    AD1CH1CON1bits.NINSEL = 0; //Single-end