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