// TI File $Revision: /main/1 $
// Checkin $Date: August 18, 2006   13:46:19 $
//###########################################################################
//
// FILE:   DSP2833x_EPwm.c
//
// TITLE:  DSP2833x ePWM Initialization & Support Functions.
//
//###########################################################################
// $TI Release: DSP2833x/DSP2823x C/C++ Header Files V1.31 $
// $Release Date: August 4, 2009 $
//###########################################################################

#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h"   // DSP2833x Examples Include File
#include "Constants.h"

#define DUTY_50_PERCENT  (TRIANGLE_PEAK / 2UL)                   // counts

#define PWM_INT_ENABLE     	0x1
#define EVT_CTR_ENABLE		0x1
#define ENABLE_SOCA_PULSE   0x1
#define SOCA_PULSE_CTR_ZERO 0x1
#define SOCA_PULSE_CTR_PRD  2

void InitEPwmTimer( void );

// Eaton funcs

//#include "InitPWM.h"
//void SetupA2DTrigger( volatile struct EPWM_REGS* regs, uint32_t adcFrequency );
//void UpdateA2DTrigger( volatile struct EPWM_REGS* regs, uint32_t adcFrequency );
//void InitEPwmTimer(void);
//void InitEPwmChannel( volatile struct EPWM_REGS* regs, uint32_t freq );
//void UpdateEPwmChannel( volatile struct EPWM_REGS* regs, uint32_t freq  );
//void InitTZ( void );


//---------------------------------------------------------------------------
// InitEPwm: 
//---------------------------------------------------------------------------
// This function initializes the ePWM(s) to a known state.
//
void InitEPwm(void)
{
   // Initialize ePWM1/2/3/4/5/6

    // ************* 
    //  Eaton code, not TI
    // *************

//    // setting up A2D trigger on ePWM4
//    // configure GPIO for eWPM
//    InitEPwmGpio();
//
//    SetupA2DTrigger( &EPwm4Regs, ADCFrequency );    // PWMA: PWM sync out/in, PWMB: A2D mux
//
//    InitEPwmTimer();                            // initialize timer control
//
//    // PWMs active high
//    InitEPwmChannel( &EPwm1Regs, PWMFrequency );    // PWMA: Inverter A
//    InitEPwmChannel( &EPwm2Regs, PWMFrequency );    // PWMA: Inverter B
//    InitEPwmChannel( &EPwm3Regs, PWMFrequency );    // PWMA: Inverter C
//
//    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;              // Set PWM1A on event A, up count
//    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;            // Clear PWM1A on event A, down count
//    EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;              // Set PWM1B on event B, up count
//    EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;            // Clear PWM1B on event B, down count
//
//    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;              // Set PWM2A on event A, up count
//    EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;            // Clear PWM2A on event A, down count
//    EPwm2Regs.AQCTLB.bit.CBU = AQ_SET;              // Set PWM2B on event B, up count
//    EPwm2Regs.AQCTLB.bit.CBD = AQ_CLEAR;            // Clear PWM2B on event B, down count
//
//    EPwm3Regs.AQCTLA.bit.CAU = AQ_SET;              // Set PWM3A on event A, up count
//    EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR;            // Clear PWM3A on event A, down count
//    EPwm3Regs.AQCTLB.bit.CBU = AQ_SET;              // Set PWM3B on event B, up count
//    EPwm3Regs.AQCTLB.bit.CBD = AQ_CLEAR;            // Clear PWM3B on event B, down count
//
//    // Special DAC function
//    InitEPwmChannel( &EPwm5Regs, DacFrequency );  // PWMA: Channel A, PWMB: Channel B
//    InitEPwmChannel( &EPwm6Regs, DacFrequency );  // PWMA: Channel C, PWMB: spare
//
//    EPwm5Regs.AQCTLA.bit.CAU = AQ_CLEAR;            // Clear PWM5A on event A, up count
//    EPwm5Regs.AQCTLA.bit.CAD = AQ_SET;              // Set PWM5A on event A, down count
//    EPwm5Regs.AQCTLB.bit.CBU = AQ_CLEAR;            // Clear PWM5B on event B, up count
//    EPwm5Regs.AQCTLB.bit.CBD = AQ_SET;              // Set PWM5B on event B, down count
//
//    EPwm6Regs.AQCTLA.bit.CAU = AQ_CLEAR;            // Clear PWM6A on event A, up count
//    EPwm6Regs.AQCTLA.bit.CAD = AQ_SET;              // Set PWM6A on event A, down count
//    EPwm6Regs.AQCTLB.bit.CBU = AQ_CLEAR;            // Clear PWM6B on event B, up count
//    EPwm6Regs.AQCTLB.bit.CBD = AQ_SET;              // Set PWM6B on event B, down count

   InitEPwmGpio();

   InitEPwmTimer();

}

//void UpdateEPwm(Uint32 newCarrierFrequency)
//{
//    uint32_t newAdcFrequency = newCarrierFrequency * 16;
//    uint32_t newDacFrequency = newCarrierFrequency * 8;
//
//    UpdateA2DTrigger( &EPwm4Regs, newAdcFrequency );    // PWMA: PWM sync out/in, PWMB: A2D mux
//
//    UpdateEPwmChannel( &EPwm1Regs, newCarrierFrequency );    // PWMA: Inverter A
//    UpdateEPwmChannel( &EPwm2Regs, newCarrierFrequency );    // PWMA: Inverter B
//    UpdateEPwmChannel( &EPwm3Regs, newCarrierFrequency );    // PWMA: Inverter C
//
//    // Special DAC function
//    UpdateEPwmChannel( &EPwm5Regs, newDacFrequency );  // PWMA: Channel A, PWMB: Channel B
//    UpdateEPwmChannel( &EPwm6Regs, newDacFrequency );  // PWMA: Channel C, PWMB: spare
//}

//---------------------------------------------------------------------------
// Example: InitEPwmGpio: 
//---------------------------------------------------------------------------
// This function initializes GPIO pins to function as ePWM pins
//
// Each GPIO pin can be configured as a GPIO pin or up to 3 different
// peripheral functional pins. By default all pins come up as GPIO
// inputs after reset.  
// 

void InitEPwmGpio(void)
{
   InitEPwm1Gpio();
   InitEPwm2Gpio();
   //InitEPwm3Gpio();
   //InitEPwm4Gpio();
   InitEPwm5Gpio();
   InitEPwm6Gpio();
}

// HWCL reference PWN, initialize to PWM now
void InitEPwm1Gpio(void)
{
   EALLOW;
   
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user. 
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;    // Enable pull-up on GPIO0 (EPWM1A)
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;    // Enable pull-up on GPIO1 (EPWM1B)   
   
/* Configure ePWM-1 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be ePWM1 functional pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;   // Configure GPIO0 as ePWM1A
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;   // Configure GPIO1 as ePWM1B
   
    EDIS;
}

// phase B rectiifer/inverter, don't configure as PWM until the legs are turned on
void InitEPwm2Gpio(void)
{
   EALLOW;
    
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user. 
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAPUD.bit.GPIO2 = 0;    // Enable pull-up on GPIO2 (EPWM2A)
    GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0;    // Enable pull-up on GPIO3 (EPWM3B)


/* Configure ePWM-2 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be ePWM2 functional pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;   // Configure GPIO2 as EPWM2A
    GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1;   // Configure GPIO3 as EPWM2B
   
    EDIS;
}

// phase C rectiifer/inverter, don't configure as PWM until the legs are turned on
void InitEPwm3Gpio(void)
{
   EALLOW;
   
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user. 
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAPUD.bit.GPIO4 = 0;    // Enable pull-up on GPIO4 (EPWM3A)
    GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0;    // Enable pull-up on GPIO5 (EPWM3B)
       
/* Configure ePWM-3 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be ePWM3 functional pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1;   // Configure GPIO4 as EPWM3A
    GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 1;   // Configure GPIO5 as EPWM3B
    
    EDIS;
}


void InitEPwm4Gpio(void)
{
   EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user. 
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

   GpioCtrlRegs.GPAPUD.bit.GPIO6 = 0;    // Enable pull-up on GPIO6 (EPWM4A)
   GpioCtrlRegs.GPAPUD.bit.GPIO7 = 0;    // Enable pull-up on GPIO7 (EPWM4B)

/* Configure ePWM-4 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be ePWM4 functional pins.
// Comment out other unwanted lines.

   GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 1;   // Configure GPIO6 as EPWM4A
   GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 1;   // Configure GPIO7 as EPWM4B
    
    EDIS;
}

void InitEPwm5Gpio(void)
{
   EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user. 
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAPUD.bit.GPIO8 = 0;    // Enable pull-up on GPIO8 (EPWM5A)
    GpioCtrlRegs.GPAPUD.bit.GPIO9 = 0;    // Enable pull-up on GPIO9 (EPWM5B)

/* Configure ePWM-5 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be ePWM5 functional pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 1;   // Configure GPIO8 as EPWM5A
    GpioCtrlRegs.GPAMUX1.bit.GPIO9 = 1;   // Configure GPIO9 as EPWM5B
    
    EDIS;
}

void InitEPwm6Gpio(void)
{
   EALLOW;

/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user. 
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

   GpioCtrlRegs.GPAPUD.bit.GPIO10 = 0;    // Enable pull-up on GPIO10 (EPWM6A)
   GpioCtrlRegs.GPAPUD.bit.GPIO11 = 0;    // Enable pull-up on GPIO11 (EPWM6B)

/* Configure ePWM-6 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be ePWM6 functional pins.
// Comment out other unwanted lines.

   GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 1;   // Configure GPIO10 as EPWM6A
   GpioCtrlRegs.GPAMUX1.bit.GPIO11 = 1;   // Configure GPIO11 as EPWM6B
    
    EDIS;
}

//---------------------------------------------------------------------------
// Example: InitEPwmSyncGpio: 
//---------------------------------------------------------------------------
// This function initializes GPIO pins to function as ePWM Synch pins
//
#if 0
void InitEPwmSyncGpio(void)
{

   EALLOW;

/* Configure EPWMSYNCI  */
   
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user. 
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

   GpioCtrlRegs.GPAPUD.bit.GPIO6 = 0;    // Enable pull-up on GPIO6 (EPWMSYNCI)
// GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;   // Enable pull-up on GPIO32 (EPWMSYNCI)    

/* Set qualification for selected pins to asynch only */
// This will select synch to SYSCLKOUT for the selected pins.
// Comment out other unwanted lines.

   GpioCtrlRegs.GPAQSEL1.bit.GPIO6 = 0;   // Synch to SYSCLKOUT GPIO6 (EPWMSYNCI)
// GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 0;  // Synch to SYSCLKOUT GPIO32 (EPWMSYNCI)    

/* Configure EPwmSync pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be EPwmSync functional pins.
// Comment out other unwanted lines.   

   GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 2;    // Enable pull-up on GPIO6 (EPWMSYNCI)
// GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 2;   // Enable pull-up on GPIO32 (EPWMSYNCI)    



/* Configure EPWMSYNC0  */

/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user. 
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

// klv: not using EPWMSYNCO, just in

// GpioCtrlRegs.GPAPUD.bit.GPIO6 = 0;    // Enable pull-up on GPIO6 (EPWMSYNC0)
//   GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;   // Enable pull-up on GPIO33 (EPWMSYNC0)    

// GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 3;    // Enable pull-up on GPIO6 (EPWMSYNC0)
//   GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 2;   // Enable pull-up on GPIO33 (EPWMSYNC0)    
    
    EDIS;
}
#endif


//---------------------------------------------------------------------------
// Example: InitTzGpio: 
//---------------------------------------------------------------------------
// This function initializes GPIO pins to function as Trip Zone (TZ) pins
//
// Each GPIO pin can be configured as a GPIO pin or up to 3 different
// peripheral functional pins. By default all pins come up as GPIO
// inputs after reset.  
// 
#if 0
void InitTzGpio(void)
{
   EALLOW;
   
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user. 
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.
   GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0;    // Enable pull-up on GPIO12 (TZ1)
   GpioCtrlRegs.GPAPUD.bit.GPIO13 = 0;    // Enable pull-up on GPIO13 (TZ2)
   GpioCtrlRegs.GPAPUD.bit.GPIO14 = 0;    // Enable pull-up on GPIO14 (TZ3)
   GpioCtrlRegs.GPAPUD.bit.GPIO15 = 0;    // Enable pull-up on GPIO15 (TZ4)

   GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0;    // Enable pull-up on GPIO16 (TZ5)
// GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0;    // Enable pull-up on GPIO28 (TZ5)

   GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;    // Enable pull-up on GPIO17 (TZ6) 
// GpioCtrlRegs.GPAPUD.bit.GPIO29 = 0;    // Enable pull-up on GPIO29 (TZ6)  
   
/* Set qualification for selected pins to asynch only */
// Inputs are synchronized to SYSCLKOUT by default.  
// This will select asynch (no qualification) for the selected pins.
// Comment out other unwanted lines.

  GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 2;  // Sync, 6 sample qual (TZ1)
  GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 2;  // Sync, 6 sample qual (TZ2)
  GpioCtrlRegs.GPAQSEL1.bit.GPIO14 = 2;  // Sync, 6 sample qual (TZ3)
  GpioCtrlRegs.GPAQSEL1.bit.GPIO15 = 2;  // Sync, 6 sample qual (TZ4)

  GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 2;  // Sync, 6 sample qual (TZ5)
// GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3;  // Asynch input GPIO28 (TZ5)

  GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 2;  // Sync, 6 sample qual (TZ6) 
// GpioCtrlRegs.GPAQSEL2.bit.GPIO29 = 3;  // Asynch input GPIO29 (TZ6)  

   
/* Configure TZ pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be TZ functional pins.
// Comment out other unwanted lines.   
   GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 1;  // Configure GPIO12 as TZ1
   GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 1;  // Configure GPIO13 as TZ2
   GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 1;  // Configure GPIO14 as TZ3
   GpioCtrlRegs.GPAMUX1.bit.GPIO15 = 1;  // Configure GPIO15 as TZ4

   GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 3;  // Configure GPIO16 as TZ5
// GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 3;  // Configure GPIO28 as TZ5

   GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 3;  // Configure GPIO17 as TZ6               
// GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 3;  // Configure GPIO29 as TZ6  

   EDIS;
}
#endif
// ***********************************************************************
/*!
     Sets up ePWM for ADC trigger, not sure which one
     so passing ePWM struct

     Eric Notes:
     - Initially, we are disabling output. See StartePWMTimers() for more
     info.
     - "stop-freeze counter operation" just means "do nothing"
 */
// ***********************************************************************
#if 0
void SetupA2DTrigger( volatile struct EPWM_REGS* regs, uint32_t adcFrequency )
{
    // EZ: I bet the stop/freeze counter just makes it not run at startup. It gets enabled to TB_COUNT_UP in StartePWMTimers().

    // ePWMRegs.TBCTL setup
    // 15:14 emulator mode  = 10        free run
    // 13 phase dir         = 0
    // 12 clkdiv            = 0         clkdiv = 1
    // 11:10 clkdiv         = 00
    // 9:8 hspclkdiv        = 00        hspclkdiv = 1
    // 7 hspclkdiv          = 0
    // 6 swfsync            = 0
    // 5:4 syncosel         = 11        disabled
    // 3 prdld              = 0         use shadow period register
    // 2 phsen              = 0         no phase register load
    // 1:0 ctrmode          = 11        stop-freeze counter operation mode
    regs->TBCTL.all = 0x8033;           
    
    // ePWMRegs.CMPCTL setup
    // 15:8: reserved or R/O    = 0000 0000
    // 7 reserved               = 0
    // 6 shdwBmode              = 1     immediate load
    // 5 reserved               = 0
    // 4 shdwAmode              = 0     A shadowed
    // 3:2 loadBmode            = 10    NA for immediate load
    // 1:0 loadAmode            = 10    load on 0 or period match
    regs->CMPCTL.all = 0x004a;

    // ePWMRegs.ETSEL setup cmprb used to trigger adc
    // 15 socBen                = 1     ePWM triggers SOCB
    // 14:12 socBsel            = 001   on timer 0 (TBCTR = 0x0000)
    // 11 socAen                = 0     no SOCA
    // 10:8 socAsel             = 000   na
    // 7:4 resvd                = 0000
    // 3 inten                  = 0     no ISR
    // 2:0 insel                = 000   NA
    regs->ETSEL.all = 0x9000;

    // ePwmRegs.ETPS setup
    // 15:14 SOCBCNT            = 00    
    // 13:12 SOCBPRD            = 01    generate on 1st event
    // 11:10 SOCACNT            = 00
    // 9:8 SOCAPRD              = 00  
    // 7:4 reserved             = 0000
    // 3:2 INTCNT               = 00
    // 1:0 INTPRD               = 00
    regs->ETPS.all = 0x1000;

    //ePwmRegs.Aqctlb setup
    regs->AQCTLB.bit.CBU = AQ_TOGGLE;

    // force output low to start
    regs->AQSFRC.bit.RLDCSF = 3;        // immediate load
    regs->AQSFRC.bit.ACTSFB = 1;        // force low
    regs->AQSFRC.bit.OTSFB = 1;         // force a zero

    // clear all event flags
    regs->ETCLR.bit.INT = 1;
    regs->ETCLR.bit.SOCA = 1;
    regs->ETCLR.bit.SOCB = 1;

    // set period
    regs->TBPRD = ( CPUFrequency / adcFrequency );
    //regs->TBCTR = 0x0000;                           // Clear counter
    regs->TBCTR = 300;                              // Clear counter
        
    // set for 50% duty
    regs->CMPB = ( ( CPUFrequency / adcFrequency ) / 2 );
}

void UpdateA2DTrigger( volatile struct EPWM_REGS* regs, uint32_t adcFrequency )
{
    // set period
    regs->TBPRD = ( CPUFrequency / adcFrequency );

    // set for 50% duty
    regs->CMPB = ( ( CPUFrequency / adcFrequency ) / 2 );
}
#endif
// ***********************************************************************
/*!
     Eric Notes:
     - EPwm1 is used for synchronization to all items with TB_SYNC_IN enabled.
     - The phase shift is needed for ?? TODO: Find out what the phase shift is for and what 300 means?
 */
// ***********************************************************************
void InitEPwmTimer(void)

{
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;      // Stop all the TB clocks
    EDIS;

//    // Setup Sync
//    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;     // Sync at counter = 0
//    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;      // Pass through
//    EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;      // Pass through
//    EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;      // Pass through
//    EPwm5Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;      // Pass through
//    EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // Dont output sync
//
//    // Allow each timer to be sync'ed
//    EPwm1Regs.TBCTL.bit.PHSEN = TB_ENABLE;
//    EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;
//    EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;
//    EPwm4Regs.TBCTL.bit.PHSEN = TB_ENABLE;
//    EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE;
//    EPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE;
//
//    EPwm1Regs.TBCTL.bit.PHSDIR = TB_UP;              //count up after sync. signal (EPWM1 Ctr. = 0)
//    EPwm2Regs.TBCTL.bit.PHSDIR = TB_UP;
//    EPwm3Regs.TBCTL.bit.PHSDIR = TB_UP;
//    EPwm4Regs.TBCTL.bit.PHSDIR = TB_UP;
//    EPwm5Regs.TBCTL.bit.PHSDIR = TB_UP;
//    EPwm6Regs.TBCTL.bit.PHSDIR = TB_UP;
//
//    EPwm1Regs.TBPHS.half.TBPHS = 0;
//    EPwm2Regs.TBPHS.half.TBPHS = 0;
//    EPwm3Regs.TBPHS.half.TBPHS = 0;
//    EPwm4Regs.TBPHS.half.TBPHS = 300;
//    EPwm5Regs.TBPHS.half.TBPHS = 0;
//    EPwm6Regs.TBPHS.half.TBPHS = 0;

	// ePWM1 is master
	// ePWM1 sync out pulse occurs when (CTR = zero)
	// ePWM[23456] pass the sync pulse along
	EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
	EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
	EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
	EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
	EPwm5Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
	EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;

	// ePWM[23456] load their time base counter from
	// their time base phase register when they get
	// a sync pulse
	EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
	EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;
	EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;
	EPwm4Regs.TBCTL.bit.PHSEN = TB_ENABLE;
	EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE;
	EPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE;

	// all carriers in sync
	// ePWM[135] count up after a sync event
	// ePWM[246] count up after a sync event
	EPwm1Regs.TBCTL.bit.PHSDIR = TB_UP;
	EPwm2Regs.TBCTL.bit.PHSDIR = TB_UP;
	EPwm3Regs.TBCTL.bit.PHSDIR = TB_UP;
	EPwm4Regs.TBCTL.bit.PHSDIR = TB_UP;
	EPwm5Regs.TBCTL.bit.PHSDIR = TB_UP;
	EPwm6Regs.TBCTL.bit.PHSDIR = TB_UP;

	// ePWM[123456] all do triangle modulation
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
    EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
    EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
    EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
    EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;

    // ePWM[123456] time base clock prescale
    // TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
    EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
    EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
    EPwm5Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
    EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
    
    // ePWM[123456] time base clock prescale
    // TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm5Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1;

	// ePWM[123456] all have same period
	EPwm1Regs.TBPRD = TRIANGLE_PERIOD;
	EPwm2Regs.TBPRD = TRIANGLE_PERIOD;
	EPwm3Regs.TBPRD = TRIANGLE_PERIOD;
	EPwm4Regs.TBPRD = TRIANGLE_PERIOD;
	EPwm5Regs.TBPRD = TRIANGLE_PERIOD;
	EPwm6Regs.TBPRD = TRIANGLE_PERIOD;

	// all carriers in sync
    // ePWM[135] start counting up from 0
    // ePWM[246] start counting up from 0
	EPwm1Regs.TBPHS.half.TBPHS = 0;
	EPwm2Regs.TBPHS.half.TBPHS = 0;
	EPwm3Regs.TBPHS.half.TBPHS = 0;
	EPwm4Regs.TBPHS.half.TBPHS = 0;
	EPwm5Regs.TBPHS.half.TBPHS = 0;
	EPwm6Regs.TBPHS.half.TBPHS = 0;

	// set ePWM[123456] time base counter initial values
    EPwm1Regs.TBCTR = EPwm1Regs.TBPHS.half.TBPHS;
    EPwm2Regs.TBCTR = EPwm2Regs.TBPHS.half.TBPHS;
    EPwm3Regs.TBCTR = EPwm3Regs.TBPHS.half.TBPHS;
    EPwm4Regs.TBCTR = EPwm4Regs.TBPHS.half.TBPHS;
    EPwm5Regs.TBCTR = EPwm5Regs.TBPHS.half.TBPHS;
    EPwm6Regs.TBCTR = EPwm6Regs.TBPHS.half.TBPHS;

    // ePWM[123456] counter CMPA register shadowed
    // ePWM[123456] counter CMPA register loaded at next carrier valley
	EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
	EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
	EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
	EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
	EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
	EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
	EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
	EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
	EPwm5Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
	EPwm5Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
	EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
	EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;

    // set initial value of ePWM[123456] CMPA
    // register to 50% duty cycle
	EPwm1Regs.CMPA.half.CMPA = DUTY_50_PERCENT;
	EPwm2Regs.CMPA.half.CMPA = DUTY_50_PERCENT;
	EPwm3Regs.CMPA.half.CMPA = DUTY_50_PERCENT;
	EPwm4Regs.CMPA.half.CMPA = DUTY_50_PERCENT;
	EPwm5Regs.CMPA.half.CMPA = DUTY_50_PERCENT;
	EPwm6Regs.CMPA.half.CMPA = DUTY_50_PERCENT;

    // Not considering deadtime, the ePWM[123456]A and ePWM[123456]B outputs
    // should always be complements of one another

    // remember PWM outputs are inverted just after coming out of CPLD and again on SIB
	// set Action Qualifier registers per "PWM with Unipolar Voltage Switching" H-Bridge control approach
	// PWMxA output controls upper or top switch
	// PWMxB output controls lower or bot switch
    // ePWM[123456]A output cleared to 0 when counting up and (TBCTR = CMPA)
    // ePWM[123456]A output set to 1 when counting down and (TBCTR = CMPA)
	EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
	EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;
	EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
	EPwm2Regs.AQCTLA.bit.CAD = AQ_SET;
	EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR;
	EPwm3Regs.AQCTLA.bit.CAD = AQ_SET;
	EPwm4Regs.AQCTLA.bit.CAU = AQ_CLEAR;
	EPwm4Regs.AQCTLA.bit.CAD = AQ_SET;
	EPwm5Regs.AQCTLA.bit.CAU = AQ_CLEAR;
	EPwm5Regs.AQCTLA.bit.CAD = AQ_SET;
	EPwm6Regs.AQCTLA.bit.CAU = AQ_CLEAR;
	EPwm6Regs.AQCTLA.bit.CAD = AQ_SET;

    // ePWM[123456]B output set to 1 when counting up and (TBCTR = CMPA)
    // ePWM[123456]B output cleared to 0 when counting down and (TBCTR = CMPA)
	EPwm1Regs.AQCTLB.bit.CAU = AQ_SET;
	EPwm1Regs.AQCTLB.bit.CAD = AQ_CLEAR;
	EPwm2Regs.AQCTLB.bit.CAU = AQ_SET;
	EPwm2Regs.AQCTLB.bit.CAD = AQ_CLEAR;
	EPwm3Regs.AQCTLB.bit.CAU = AQ_SET;
	EPwm3Regs.AQCTLB.bit.CAD = AQ_CLEAR;
	EPwm4Regs.AQCTLB.bit.CAU = AQ_SET;
	EPwm4Regs.AQCTLB.bit.CAD = AQ_CLEAR;
	EPwm5Regs.AQCTLB.bit.CAU = AQ_SET;
	EPwm5Regs.AQCTLB.bit.CAD = AQ_CLEAR;
	EPwm6Regs.AQCTLB.bit.CAU = AQ_SET;
	EPwm6Regs.AQCTLB.bit.CAD = AQ_CLEAR;

    // trigger ADC at valley of triangle
    EPwm1Regs.ETSEL.bit.SOCAEN  = ENABLE_SOCA_PULSE;
    EPwm1Regs.ETSEL.bit.SOCASEL = SOCA_PULSE_CTR_ZERO;
    EPwm1Regs.ETPS.bit.SOCAPRD  = ET_1ST;               // Generate pulse on 1st event

    // trigger Interrupt at valley of triangle
    EPwm1Regs.ETSEL.bit.INTEN  = PWM_INT_ENABLE;
    EPwm1Regs.ETSEL.bit.INTSEL = SOCA_PULSE_CTR_ZERO;
    EPwm1Regs.ETPS.bit.INTPRD  = ET_1ST;               // Generate pulse on 1st event


    // PWMA output used to generate PWMB output
    // dead-band active high with complementary outputs
    // dead-band enabled with minimum delay count by default
    EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
    EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;
    EPwm3Regs.DBCTL.bit.IN_MODE = DBA_ALL;
    EPwm4Regs.DBCTL.bit.IN_MODE = DBA_ALL;
    EPwm5Regs.DBCTL.bit.IN_MODE = DBA_ALL;
    EPwm6Regs.DBCTL.bit.IN_MODE = DBA_ALL;

    EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
    EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
    EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
    EPwm4Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
    EPwm5Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
    EPwm6Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;

    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    EPwm4Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    EPwm5Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    EPwm6Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;

    // rising and falling edge delay regs are 10 bit unsigned integers
    // with range   1 <= value <= 1023
    EPwm1Regs.DBRED = 1;  // rising edge delay
    EPwm2Regs.DBRED = 1;
    EPwm3Regs.DBRED = 1;
    EPwm4Regs.DBRED = 1;
    EPwm5Regs.DBRED = 1;
    EPwm6Regs.DBRED = 1;

    EPwm1Regs.DBFED = 1;  // falling edge delay
    EPwm2Regs.DBFED = 1;
    EPwm3Regs.DBFED = 1;
    EPwm4Regs.DBFED = 1;
    EPwm5Regs.DBFED = 1;
    EPwm6Regs.DBFED = 1;

}


//void InitEPwmChannel( volatile struct EPWM_REGS* regs, uint32_t freq  )
//{
//    // Setup TBCLK
//    regs->TBPRD = ( ( CPUFrequency / freq ) / 2 );
//    regs->TBCTR = 0x0000;                           // Clear counter
//
//    // Setup counter mode
//    regs->TBCTL.bit.CTRMODE = TB_FREEZE;            // Don't start timer yet
//    regs->TBCTL.bit.HSPCLKDIV = TB_DIV1;            // Clock ratio to SYSCLKOUT
//    regs->TBCTL.bit.CLKDIV = TB_DIV1;
//
//    // Setup shadowing
//    regs->CMPCTL.bit.SHDWAMODE = CC_SHADOW;
//    regs->CMPCTL.bit.SHDWBMODE = CC_SHADOW;
//    regs->CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD;   // Load on Zero or period match
//    regs->CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD;
//
//}

//void UpdateEPwmChannel( volatile struct EPWM_REGS* regs, uint32_t freq  )
//{
//    regs->TBPRD = ( ( CPUFrequency / freq ) / 2 );
//}

void StartePWMTimers( void )
{
    EALLOW;
//    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
//    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
//    EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
//    EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
//    EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
//    EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;         // Start all the timers synced
    EDIS;
}

//void StopePWMTimers( void )
//{
//    EALLOW;
//
//    EPwm1Regs.TBCTL.bit.CTRMODE = TB_FREEZE;
//    EPwm2Regs.TBCTL.bit.CTRMODE = TB_FREEZE;
//    EPwm3Regs.TBCTL.bit.CTRMODE = TB_FREEZE;
//    EPwm4Regs.TBCTL.bit.CTRMODE = TB_FREEZE;
//    EPwm5Regs.TBCTL.bit.CTRMODE = TB_FREEZE;
//    EPwm6Regs.TBCTL.bit.CTRMODE = TB_FREEZE;
//
//    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
//    EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;
//    EPwm3Regs.TBCTL.bit.PHSEN = TB_DISABLE;
//    EPwm4Regs.TBCTL.bit.PHSEN = TB_DISABLE;
//    EPwm5Regs.TBCTL.bit.PHSEN = TB_DISABLE;
//    EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;
//
//    EPwm1Regs.TBCTR = 0;
//    EPwm2Regs.TBCTR = 0;
//    EPwm3Regs.TBCTR = 0;
//    EPwm4Regs.TBCTR = 0;
//    EPwm5Regs.TBCTR = 0;
//    EPwm6Regs.TBCTR = 0;
//
//    EPwm1Regs.TBCTL.bit.PHSDIR = TB_UP;
//    EPwm2Regs.TBCTL.bit.PHSDIR = TB_UP;
//    EPwm3Regs.TBCTL.bit.PHSDIR = TB_UP;
//    EPwm4Regs.TBCTL.bit.PHSDIR = TB_UP;
//    EPwm5Regs.TBCTL.bit.PHSDIR = TB_UP;
//    EPwm6Regs.TBCTL.bit.PHSDIR = TB_UP;
//
//    EPwm1Regs.TBPHS.half.TBPHS = 0;
//    EPwm2Regs.TBPHS.half.TBPHS = 0;
//    EPwm3Regs.TBPHS.half.TBPHS = 0;
//    EPwm4Regs.TBPHS.half.TBPHS = 0;
//    EPwm5Regs.TBPHS.half.TBPHS = 0;
//    EPwm6Regs.TBPHS.half.TBPHS = 0;
//
//    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
//    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
//    EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
//    EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
//    EPwm5Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
//    EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
//
//    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
//    SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 0;
//    SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 0;
//    SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 0;
//    SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 0;
//    SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 0;
//    SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 0;
//
//    EDIS;
//}
    
// ***********************************************************************
// *
// *    FUNCTION: InitTZ 
// *
// *    DESCRIPTION: Initializes TZ, one-shot no-action taken. Is used
// *                 for indication only, gate is controlled in the PLD
// *                 TZ1 = inverter phA
// *                 TZ2 = inverter phB
// *                 TZ3 = inverter phC
// *                 TZ4 = rectifier phA
// *                 TZ5 = rectifier phB
// *                 TZ6 = rectifier phC
// *
// *    ARGUMENTS: 
// *
// *    RETURNS: 
// *
// ***********************************************************************
//void InitTZ( void )
//{
//    EALLOW;
//
//    // Inverter phA to TZ1, phB to TZ2, phC to TZ3
//    EPwm1Regs.TZSEL.bit.OSHT1 = 1;      // one-shot
//    EPwm1Regs.TZSEL.bit.OSHT2 = 1;
//    EPwm1Regs.TZSEL.bit.OSHT3 = 1;
//    EPwm1Regs.TZCTL.all = 0x000f;       // no-action for a or b
//    EPwm1Regs.TZEINT.all = 0;           // no TZ interrupts
//    EPwm1Regs.TZCLR.all = 7;            // clear any spurious flags
//
//    // Rectifier phA to TZ4, phB to TZ5, phC to TZ6
//    EPwm3Regs.TZSEL.bit.OSHT4 = 1;      // one-shot
//    EPwm3Regs.TZSEL.bit.OSHT5 = 1;
//    EPwm3Regs.TZSEL.bit.OSHT6 = 1;
//    EPwm3Regs.TZCTL.all = 0x000f;       // no-action for a or b
//    EPwm3Regs.TZEINT.all = 0;           // no TZ interrupts
//    EPwm3Regs.TZCLR.all = 7;            // clear any spurious flags
//
//    EDIS;
//}


