Data Updates and Override
Void __inline__ PWM_AllRegistersWrite (void)
{
// Master writes – note MPER set to MAX_PERIOD in init routine
MPHASE = priPWMHighPhase;
MDC = priPWMHighDuty;
AMPHASE = syncPWMHighPhase;
AMDC = syncPWMHighDuty;
PG1PER = llcPeriod;
PG1TRIGA = priPWMLowTrigA;
PG1TRIGB = priPWMLowTrigB;
PG1TRIGC = phase120OffSetDaisyChain;
PG1TRIGD = phase240OffSetDaisyChain;
PG2PHASE = syncPWMHighPhase;
PG2DC = syncPWMHighDuty;
PG2TRIGA = syncPWMLowTrigA;
PG2TRIGB = syncPWMLowTrigB;
PG2TRIGC = phase90OffSetDaisyChain;
PG3TRIGA = PG4TRIGA = PG5TRIGA = priPWMLowTrigA;
PG3TRIGB = PG4TRIGB = PG5TRIGB = priPWMLowTrigB;
PG5TRIGC = phase120OffSetDaisyChain;
PG5TRIGD = phase240OffSetDaisyChain;
PG6PHASE = syncPWMHighPhase;
PG6DC = syncPWMHighDuty;
PG6TRIGA = syncPWMLowTrigA;
PG6TRIGB = syncPWMLowTrigB;
PG7TRIGA = PG8TRIGA = priPWMLowTrigA;
PG7TRIGB = PG8TRIGB = priPWMLowTrigB;
APG1TRIGA = APG2TRIGA = APG3TRIGA = APG4TRIGA = syncPWMLowTrigA;
APG1TRIGB = APG2TRIGB = APG3TRIGB = APG4TRIGB = syncPWMLowTrigB;
}
void __attribute__ ((interrupt, no_auto_psv, context)) _T1Interrupt(void)
{
// Simulate ADC ISR at 100 kHz
_T1IF = 0;
// Sweep period up and down
if (up_down == 0) {
ctrlOutput -= PERIOD_CHANGE;}
else {
ctrlOutput += PERIOD_CHANGE;}
if (ctrlOutput >= MAX_PERIOD + 64){
up_down = 0;
ctrlOutput = MAX_PERIOD;}
else if (ctrlOutput <= MIN_PERIOD){
up_down = 1;
ctrlOutput = MIN_PERIOD;}
if ((updateFlag == 0) && (PG8STATbits.UPDATE == 0))
{
priSyncDiffRising = SYNC_DIFF_RISE; // Can be runtime configurable
priSyncDiffFalling = SYNC_DIFF_FALL;
llcPeriod = ctrlOutput & 0xFFFF0;
phase120OffSetDaisyChain = (__builtin_muluu_32(llcPeriod, 1365)>>12);
phase120OffSetDaisyChain & = 0xFFFF0;
phase90OffSetDaisyChain = (llcPeriod>>2) & 0xFFFF0;
phase240OffSetDaisyChain = phase120OffSetDaisyChain<<1;
priPWMHighPhase = DEADTIME; // Can be runtime configurable
priPWMHighDuty = (llcPeriod >> 1);
priPWMLowTrigA = priPWMHighDuty + deadTime;
priPWMLowTrigB = llcPeriod;
syncPWMHighPhase = DEADTIME + priSyncDiffRising;
syncPWMHighDuty = (llcPeriod >> 1) - priSyncDiffFalling;
syncPWMLowTrigA = priPWMLowTrigA + priSyncDiffRising;
syncPWMLowTrigB = priPWMLowTrigB - priSyncDiffFalling;
PWM_AllRegistersWrite();
updateFlag = 1; // All data written, ready for PWM update - PWM8 IRS
_PWM8IF = 0;
_PWM8IE = 1; // Enable PWM8 ISR for scheduling
}
}
void __attribute__ ((interrupt, no_auto_psv, context)) _PWM8Interrupt(void) {
if (updateFlag == 1) {
PG1STATbits.UPDREQ = 1;
APG1STATbits.UPDREQ = 1;
updateFlag = 0;
}
_PWM8IE = 0;
_PWM8IF = 0; // Disable PWM8 ISR until next write cycle complete
}
void PrimaryOverride(void) {
PG1IOCON2 |= 0x00300000;
PG3IOCON2 |= 0x00300000;
PG4IOCON2 |= 0x00300000;
PG5IOCON2 |= 0x00300000;
PG7IOCON2 |= 0x00300000;
PG8IOCON2 |= 0x00300000;
}
void SecondaryOverride(void) {
PG2IOCON2 |= 0x00300000;
PG6IOCON2 |= 0x00300000;
APG1IOCON2 |= 0x00300000;
APG2IOCON2 |= 0x00300000;
APG3IOCON2 |= 0x00300000;
APG4IOCON2 |= 0x00300000;
}
void PrimaryOverrideDisable(void) {
PG1IOCON2 &= 0xFFCFFFFF;
PG3IOCON2 &= 0xFFCFFFFF;
PG4IOCON2 &= 0xFFCFFFFF;
PG5IOCON2 &= 0xFFCFFFFF;
PG7IOCON2 &= 0xFFCFFFFF;
PG8IOCON2 &= 0xFFCFFFFF;
}
void SecondaryOverrideDisable(void) {
PG2IOCON2 &= 0xFFCFFFFF;
PG6IOCON2 &= 0xFFCFFFFF;
APG1IOCON2 &= 0xFFCFFFFF;
APG2IOCON2 &= 0xFFCFFFFF;
APG3IOCON2 &= 0xFFCFFFFF;
}