10 Appendix A: Code Example, PWM initialization

PWM initialization

#define MAX_PERIOD  (255984 & 0xFFFF0)                  // 50 kHz
#define MIN_PERIOD  (36555 & 0xFFFF0)                   // 350 kHz
#define DEADTIME    0		                           // User defined                    
#define SYNC_DIFF_RISE   0       	                   // SR delay rising edge – User defined
#define SYNC_DIFF_FALL  0                               // SR delay falling edge – User defined
#define INIT_DUTY       (MIN_PERIOD/2)                  // 50% DC
#define INIT_120_DEG    ((MIN_PERIOD/3) & 0xFFFF0)      // Initial 120* SOC trigger 
#define INIT_240_DEG    ((MIN_PERIOD*2/3) & 0xFFFF0)    // Initial 240* SOC trigger
#define INIT_90_DEG    ((MIN_PERIOD/4) & 0xFFFF0)       // Initial 90* SOC trigger
      
#define PERIOD_CHANGE    10             // Change step size for period sweep

uint32_t llcPeriod;                     // System period
uint32_t ctrlOutput = MIN_PERIOD;       // Simulated ADC data used for period update
uint32_t priSyncDiffRising;             // Secondary sync delay, rising edge
uint32_t priSyncDiffFalling;            // Secondary sync delay, falling edge
uint32_t priPWMHighPhase;               // Primary PWMxH rising edge
uint32_t priPWMHighDuty;                // Primary PWMxH falling edge
uint32_t priPWMLowTrigA;                // Primary PWMxL rising edge
uint32_t priPWMLowTrigB;                // Primary PWMxL falling edge
uint32_t syncPWMHighPhase;              // Secondary PWMxH rising edge
uint32_t syncPWMHighDuty;               // Secondary PWMxH falling edge
uint32_t syncPWMLowTrigA;               // Secondary PWMxL rising edge
uint32_t syncPWMLowTrigB;               // Secondary PWMxL falling edge
uint32_t phase120OffSetDaisyChain;      // 120* SOC trigger offset
uint32_t phase240OffSetDaisyChain;      // 240* SOC trigger offset
uint32_t phase90OffSetDaisyChain;       // 90* SOC trigger offset for 2nd bank
uint16_t updateFlag = 0;                // Flag to block writes if update still in progress

void PWM_Initialize (void)
{

    PCLKCONbits.MCLKSEL = 1;
    APCLKCONbits.MCLKSEL = 1;

    /* PWM Events *************************************************************/    
    
    // Bank 1 SOC Trigger events
    // PWM Event A is used for PG4/APG2 SOC trigger (120 deg of PG1)
    PWMEVTAbits.EVTAPGS = 0b000;    	 // PG1 
    PWMEVTAbits.EVTASEL = 0b01001;  	 // ADC Trigger 1
    // PWM Event B is used for PG3/APG1 SOC trigger (240 deg of PG1)
    PWMEVTBbits.EVTBPGS = 0b000;    	 // PG1
    PWMEVTBbits.EVTBSEL = 0b01011;  	 // DAC Trigger    
    
    // Bank 2 SOC Trigger events
    // PWM Event C is used for PG7/APG3 SOC trigger (120 deg from PG5)
    PWMEVTCbits.EVTCPGS = 0b100;    	 // PG5
    PWMEVTCbits.EVTCSEL = 0b01001;  	 // ADC Trigger 1
    
    // PWM Event D is used for PG8/APG4 SOC trigger (240 deg from PG5)
    PWMEVTDbits.EVTDPGS = 0b100;    	 // PG5
    PWMEVTDbits.EVTDSEL = 0b01011;  	 // DAC Trigger
    PWMEVTDbits.EVTDOEN = 1;        	 // Enable output to route to virtual pin
   
   // For this psuedo code, all PGs and APGs need to be configured as follows:
   // PGxCONbits.MODSEL = 0b010;  	  // Independent Edge PWM mode, dual output
   // PGxCONbits.CLKSEL = 0b01;   	  // PG uses MCLK
   // PGxIOCON1bits.PENL = 1;     	  // Enable L output
   // PGxIOCON1bits.PENH = 1;     	  // Enable H output
   // PGxIOCON1bits.PMOD = 0b01;  	  // Independent output mode
   // PGxIOCON1bits.PPSEN = 1;   	   // Remap PWM outputs via PPS (if needed)
   // Settings below are specific to each PG

    /* PG1 ********************************************************************/
    /* Bank 1, phase A, Primary ***********************************************/
    PG1CONbits.SOCS = 0b0000;   	    // Self triggered
    PG1CONbits.UPDMOD = 0b000;  	    // Self SOC
    PG1CONbits.MSTEN = 1;       	    // PG1 is Master update broadcast
    PG1CONbits.MPHSEL = 1;      	    // Use Master Phase 
    PG1CONbits.MDCSEL = 1;      	    // Use Master DC

    PG1EVT1bits.ADTR1EN3 = 1;   	    // ADC Trigger 1 event is PG1TRIGC (120*)
    PG1EVT1bits.DACTREN1 = 1;   	    // DAC Trigger event is PG1TRIGD (240*)
    PG1EVT1bits.PGTRGSEL = 0b000;   	// PGTRIGOUT is EOC

    /* PG2 ********************************************************************/
    /* Bank 1, phase A, Secondary *********************************************/
    PG2CONbits.SOCS = 0b0001;   	   // Use PG1's PGTRGOUT
    PG2CONbits.TRGMOD = 0b01;   	   // Re-triggerable
    PG2CONbits.UPDMOD = 0b010; 	    // Client SOC
    PG2CONbits.MPERSEL = 1;     	   // Use MPER
    PG2IOCON2bits.OSYNC = 0b10; 	   // Override specified by UPDMOD
    PG2EVT1bits.PGTRGSEL = 0b011;      // PGTRIGOUT event is PG2TRIGC, 90* to PG5
   
    /* PG3 ********************************************************************/    
    /* Bank 1, phase B, Primary ***********************************************/
    PG3CONbits.SOCS = 0b1111;   	   // Sync PCI as Start-of-cycle
    PG3CONbits.TRGMOD = 0b01;   	   // Re-triggerable
    PG3CONbits.UPDMOD = 0b010;  	   // Client SOC
    PG3CONbits.MPHSEL = 1;      	   // Use MPHASE
    PG3CONbits.MPERSEL = 1;     	   // Use MPER 
    PG3CONbits.MDCSEL = 1;     	    // Use MDC
    PG3IOCON2bits.OSYNC = 0b10; 	   // Override specified by UPDMOD    

    PG3SPCI1bits.TERM = 0b001;  	   // Auto-terminate
    PG3SPCI1bits.TSYNCDIS = 1;  	   // Termination of latched PCI occurs immediately 
    PG3SPCI1bits.ACP = 0b001;   	   // Rising edge
    PG3SPCI2 = 1<<23;           	   // PCI source is PWMEVTA (120*)

    /* APG1 *******************************************************************/
    /* Bank 1, phase B, Secondary *********************************************/    
    APG1CONbits.SOCS = 0b1111;  	   // Sync PCI as Start-of-cycle
    APG1CONbits.TRGMOD = 0b01;  	   // Re-triggerable  
    APG1CONbits.UPDMOD = 0b000; 	   // Self SOC
    APG1CONbits.MSTEN = 1;      	   // APG1 is Master update broadcast
    APG1CONbits.MPHSEL = 1;     	   // Use MPHASE     
    APG1CONbits.MPERSEL = 1;    	   // Use MPER
    APG1CONbits.MDCSEL = 1;     	   // Use MDC
    APG1IOCON2bits.OSYNC = 0b10;	   // Override specified by UPDMOD
    
    APG1SPCI1bits.TERM = 0b001; 	   // Auto-terminate
    APG1SPCI1bits.TSYNCDIS = 1; 	   // Termination of latched PCI occurs immediately
    APG1SPCI1bits.ACP = 0b001;  	   // Rising edge
    APG1SPCI2 = 1<<23;          	   // PCI source is PWMEVTA (120*)

    /* PG4 ********************************************************************/
    /* Bank 1, phase C, Primary ***********************************************/
    PG4CONbits.SOCS = 0b1111;   	   // Sync PCI as Start-of-cycle
    PG4CONbits.TRGMOD = 0b01;   	   // Re-triggerable
    PG4CONbits.UPDMOD = 0b010;  	   // Client SOC
    PG4CONbits.MPHSEL = 1;      	   // Use MPHASE
    PG4CONbits.MPERSEL = 1;              // Use MPER 
    PG4CONbits.MDCSEL = 1;      	   // Use MDC
    PG4IOCON2bits.OSYNC = 0b10; 	   // Override specified by UPDMOD
    
    PG4SPCI1bits.TERM = 0b001;  	   // Auto-terminate
    PG4SPCI1bits.TSYNCDIS = 1;  	   // Termination of latched PCI occurs immediately
    PG4SPCI1bits.ACP = 0b001;   	   // Rising edge
    PG4SPCI2 = 1<<24;           	   // PCI source is PWMEVTB (240*)

    /* APG2 *******************************************************************/
    /* Bank 1, phase C, Secondary *********************************************/    
    APG2CONbits.SOCS = 0b1111;  	   // Sync PCI as Start-of-cycle
    APG2CONbits.TRGMOD = 0b01;  	   // Re-triggerable
    APG2CONbits.UPDMOD = 0b010; 	   // Client SOC
    APG2CONbits.MPHSEL = 1;     	   // Use MPHASE
    APG2CONbits.MPERSEL = 1;   	    // Use MPER 
    APG2CONbits.MDCSEL = 1;     	   // Use MDC
    APG2IOCON2bits.OSYNC = 0b10;	   // Override specified by UPDMOD    

    APG2SPCI1bits.TERM = 0b001; 	   // Auto-terminate
    APG2SPCI1bits.TSYNCDIS = 1; 	   // Termination of latched PCI occurs immediately
    APG2SPCI1bits.ACP = 0b001;  	   // Rising edge
    APG2SPCI2 = 1<<24;         	    // PCI source is PWMEVTB (240*)
    
    /******************The Second 3 Phase Interleaved LLC**********************/
        
    /* PG5 ********************************************************************/
    /* Bank 2, phase A, Primary ***********************************************/
    PG5CONbits.SOCS = 0b0010;   	   // SOC is PG2's PGTRIGOUT (90* to PG2 and PG1)
    PG5CONbits.TRGMOD = 0b01;  	    // Re-triggerable
    PG5CONbits.UPDMOD = 0b010;  	   // Client SOC
    PG5CONbits.MPHSEL = 1;      	   // Use MPHASE
    PG5CONbits.MPERSEL = 1;     	   // Use MPER
    PG5CONbits.MDCSEL = 1;      	   // Use MDC
    PG5IOCON2bits.OSYNC = 0b10; 	   // Override specified by UPDMOD    

    PG5EVT1bits.ADTR1EN3 = 1;   	   // ADC trigger 1 event is PG5TRIGC (120*)
    PG5EVT1bits.DACTREN1 = 1;   	   // DAC trigger event is PG5TRIGD (240*)
    PG5EVT1bits.PGTRGSEL = 0b101;      // PGTRIGOUT event is PG5TRIGE, SOC to PG6

    /* PG6 ********************************************************************/
    /* Bank 2, phase A, Secondary *********************************************/
    PG6CONbits.SOCS = 0b0101;   	   // SOC is PG5's TRIGE, PG5 SOC
    PG6CONbits.TRGMOD = 0b01;   	   // Re-triggerable
    PG6CONbits.UPDMOD = 0b010;  	   // Client SOC
    PG6CONbits.MPERSEL = 1;     	   // Use MPER
    PG6IOCON2bits.OSYNC = 0b10; 	   // Override specified by UPDMOD    
    
    /* PG7 ********************************************************************/
    /* Bank 2, phase B, Primary ***********************************************/
    PG7CONbits.SOCS = 0b1111;   	 // Sync PCI as Start-of-cycle
    PG7CONbits.TRGMOD = 0b01;   	 // Re-triggerable
    PG7CONbits.UPDMOD = 0b010;  	 // Client SOC
    PG7CONbits.MPHSEL = 1;      	 // Use MPHASE
    PG7CONbits.MPERSEL = 1;     	 // Use MPER
    PG7CONbits.MDCSEL = 1;      	 // Use MDC
    PG7IOCON2bits.OSYNC = 0b10; 	 // Override specified by UPDMOD

    PG7SPCI1bits.TERM = 0b001;  	  // Auto-terminate
    PG7SPCI1bits.TSYNCDIS = 1;  	  // Termination of latched PCI occurs immediately
    PG7SPCI1bits.ACP = 0b001;   	  // Rising edge
    PG7SPCI2 = 1<<25;           	  // PCI source is PWMEVTC (120*)
    
    /* APG3 *******************************************************************/
    /* Bank 2, phase B, Secondary *********************************************/
    APG3CONbits.SOCS = 0b1111;   	// Sync PCI as Start-of-cycle
    APG3CONbits.TRGMOD = 0b01;   	// Re-triggerable
    APG3CONbits.UPDMOD = 0b010;  	// Client SOC
    APG3CONbits.MPHSEL = 1;      	// Use MPHASE
    APG3CONbits.MPERSEL = 1;     	// Use MPER  
    APG3CONbits.MDCSEL = 1;      	// Use MDC
    APG3IOCON2bits.OSYNC = 0b10; 	// Override specified by UPDMOD

    APG3SPCI1bits.TERM = 0b001; 	// Auto-terminate
    APG3SPCI1bits.TSYNCDIS = 1; 	// Termination of latched PCI occurs immediately
    APG3SPCI1bits.ACP = 0b001;  	// Rising edge
    APG3SPCI2 = 1<<25;          	// PCI source is PWMEVTC (120*)

    /* PG8 ********************************************************************/
    /* Bank 2, phase C, Primary ***********************************************/
    PG8CONbits.SOCS = 0b1111;   	// Sync PCI as Start-of-cycle
    PG8CONbits.TRGMOD = 0b01;   	// Re-triggerable
    PG8CONbits.UPDMOD = 0b010;  	// Client SOC
    PG8CONbits.MPHSEL = 1;      	// Use MPHASE
    PG8CONbits.MPERSEL = 1;     	// Use MPER 
    PG8CONbits.MDCSEL = 1;      	// Use MDC
    PG8IOCON2bits.OSYNC = 0b10; 	// Override specified by UPDMOD

    PG8EVT1bits.IEVTSEL = 0b11; 	// Timebase interrupts disabled 
    PG8EVT1bits.SIEN = 1;      	 // PG8 Interrupt is sync PCI

    PG8SPCI1bits.TERM = 0b001;  	// Auto-terminate
    PG8SPCI1bits.TSYNCDIS = 1;  	// Termination of latched PCI occurs immediately
    PG8SPCI1bits.ACP = 0b001;   	// Rising edge
    PG8SPCI2 = 1<<22;           	// PCI source is PCI input 22 (240*)

    /* APG4 *******************************************************************/
    /* Bank 2, phase C, Secondary *********************************************/
    APG4CONbits.SOCS = 0b1111;   	// Sync PCI as Start-of-cycle
    APG4CONbits.TRGMOD = 0b01;   	// Re-triggerable
    APG4CONbits.UPDMOD = 0b010;  	// Client SOC
    APG4CONbits.MPHSEL = 1;      	// Use MPHASE
    APG4CONbits.MPERSEL = 1;     	// Use MPER 
    APG4CONbits.MDCSEL = 1;      	// Use MDC
    APG4IOCON2bits.OSYNC = 0b10; 	// Override specified by UPDMOD
    
    APG4SPCI1bits.TERM = 0b001;  	// Auto-terminate
    APG4SPCI1bits.TSYNCDIS = 1;  	// Termination of latched PCI occurs immediately
    APG4SPCI1bits.ACP = 0b001;   	// Rising edge
    APG4SPCI2 = 1<<22;           	// PCI source is PCI input 22 (240*)


    /* Data Initialization ****************************************************/    
    MPER = MAX_PERIOD;		      // Set to max and controlled through PG triggers
    MPHASE = DEADTIME;
    MDC = INIT_DUTY;
    
    AMPER = MAX_PERIOD;
    AMPHASE = DEADTIME + SYNC_DIFF_RISE;
    AMDC = INIT_DUTY - SYNC_DIFF_FALL;
    
    PG1PER = MIN_PERIOD;
    PG1PHASE = DEADTIME;
    PG1TRIGA = INIT_DUTY + DEADTIME;
    PG1TRIGB = MIN_PERIOD;      
    PG1TRIGC = INIT_120_DEG;  
    PG1TRIGD = INIT_240_DEG;    

    PG2PHASE = DEADTIME + SYNC_DIFF_RISE;
    PG2DC = INIT_DUTY - SYNC_DIFF_FALL;
    PG2TRIGA = INIT_DUTY + DEADTIME + SYNC_DIFF_RISE;
    PG2TRIGB = MIN_PERIOD - SYNC_DIFF_FALL;
    PG2TRIGC = INIT_90_DEG;
    
    PG3TRIGA = PG4TRIGA = PG5TRIGA = (INIT_DUTY + DEADTIME);
    PG3TRIGB = PG4TRIGB = PG5TRIGB = MIN_PERIOD;
    PG5TRIGC = INIT_120_DEG;
    PG5TRIGD = INIT_240_DEG; 
    
    PG6PHASE = DEADTIME + SYNC_DIFF_RISE;
    PG6DC = INIT_DUTY - SYNC_DIFF_FALL;
    PG6TRIGA = INIT_DUTY + DEADTIME + SYNC_DIFF_RISE;
    PG6TRIGB = MIN_PERIOD - SYNC_DIFF_FALL;
    
    PG7TRIGA = PG8TRIGA = (INIT_DUTY + DEADTIME);
    PG7TRIGB = PG8TRIGB = MIN_PERIOD;

    APG1TRIGA = APG2TRIGA = APG3TRIGA = APG4TRIGA = (INIT_DUTY+DEADTIME+SYNC_DIFF_RISE);
    APG1TRIGB = APG2TRIGB = APG3TRIGB = APG4TRIGB = (MIN_PERIOD - SYNC_DIFF_FALL);
        
    // Clear Override data for all PGs, cleared by default
    // i.e. PG1IOCON2bits.OVRDAT = 0b00;
    
    // Enable all PWM Modules APGx’s and PGx’s with PG1 last
    // i.e. .., ..., ..; PG1CONbits.ON = 1U;
}