/* ==============================================================================
System Name: Micro stepping bipolar drive for two-phase stepping motor

File Name:	ecs_main.c

Description:	Primary system file

Originator:		ECS Development

Target:  TMS320F2808

=====================================================================================
 History:
-------------------------------------------------------------------------------------
 06-15-2006	Release	Rev 1.0 : Original release
=================================================================================  */

// Include header files used in the main function
#include "ECS_MAIN.h"

// Global variables used in this system
float T = 0.001/ISR_FREQUENCY;    // Samping period (sec), see ECS_MAIN.h
float IpeakRef = 0.2;			  // Ipeak reference (pu) 
float SpeedRef = 1.0;             // Speed reference (pu) 

unsigned int IsrTicker = 0;
unsigned int BackTicker = 0;
volatile unsigned int EnableFlag = FALSE;

int DlogCh1 = 0;
int DlogCh2 = 0;
int DlogCh3 = 0;
int DlogCh4 = 0;
DLOG_4CH dlog = DLOG_4CH_DEFAULTS;      

// Stepping motor 1
MICROSTEP motor1 = MICROSTEP_DEFAULTS;

//PWM3PH pwm1 = PWM3PH_DEFAULTS;
uSTEP_8S pwm1 = uSTEP_8S_DEFAULTS;
ADC6CH adc1 = ADC6CH_DEFAULTS;


void main(void)
{

// Initialize System Control registers, PLL, WatchDog, Clocks to default state:
        // This function is found in the DSP280x_SysCtrl.c file.
	InitSysCtrl();

// Globally synchronize all ePWM modules to the time base clock (TBCLK)
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;

// HISPCP prescale register settings, normally it will be set to default values
    EALLOW;   // This is needed to write to EALLOW protected registers
    SysCtrlRegs.HISPCP.all = 0x0000;     // SYSCLKOUT/1 
    EDIS;   // This is needed to disable write to EALLOW protected registers 

// Disable and clear all CPU interrupts:
	DINT;
	IER = 0x0000;
	IFR = 0x0000;

// Initialize Pie Control Registers To Default State:
        // This function is found in the DSP280x_PieCtrl.c file.
	InitPieCtrl();

// Initialize the PIE Vector Table To a Known State:
        // This function is found in DSP280x_PieVect.c.
	// This function populates the PIE vector table with pointers
        // to the shell ISR functions found in DSP280x_DefaultIsr.c.
	InitPieVectTable();	

// User specific functions, Reassign vectors (optional), Enable Interrupts:

   // Waiting for enable flag set
   while (EnableFlag==FALSE) { 
      BackTicker++;
    }

// Enable CNT_zero interrupt using EPWM1 Time-base
    EPwm1Regs.ETSEL.bit.INTEN = 1;   // Enable EPWM1INT generation 
    EPwm1Regs.ETSEL.bit.INTSEL = 1;  // Enable interrupt CNT_zero event
    EPwm1Regs.ETPS.bit.INTPRD = 1;   // Generate interrupt on the 1st event
    EPwm1Regs.ETCLR.bit.INT = 1;     // Enable more interrupts

// Reassign ISRs. 
        // Reassign the PIE vector for EPWM1_INT to point to a different 
        // ISR then the shell routine found in DSP280x_DefaultIsr.c.
        // This is done if the user does not want to use the shell ISR routine
        // but instead wants to use their own ISR.

	EALLOW;	// This is needed to write to EALLOW protected registers
	PieVectTable.EPWM1_INT = &ControlLoop1;
	EDIS;   // This is needed to disable write to EALLOW protected registers

// Enable PIE group 3 interrupt 1 for EPWM1_INT
    PieCtrlRegs.PIEIER3.all = M_INT1;

// Enable CPU INT3 for EPWM1_INT:
	IER |= M_INT3;



// ***************** LEVEL1 *****************
#if (BUILDLEVEL==LEVEL1)

    MICROSTEP_Init(&motor1);

    // Initialize PWM module
    pwm1.PeriodMax = (SYSTEM_FREQUENCY*1000000*T)/2;  // Perscaler X1 (T1), ISR period = T x 1, Asymmetric PWM 
	pwm1.init(&pwm1);

    // Initialize ADC module
	adc1.ChSelect1 = 0x3210;
	adc1.ChSelect2 = 0x0054;
	adc1.init(&adc1);

#endif // (BUILDLEVEL==LEVEL1)


// Initialize DATALOG module
    dlog.iptr1 = &DlogCh1;
    dlog.iptr2 = &DlogCh2;
    dlog.iptr3 = &DlogCh3;
    dlog.iptr4 = &DlogCh4;
    dlog.trig_value = 0x4000;
    dlog.size = 0x400;
    dlog.prescalar = 20;
    dlog.init(&dlog);


// Enable global Interrupts and higher priority real-time debug events:
	EINT;   // Enable Global interrupt INTM
	ERTM;	// Enable Global realtime interrupt DBGM

// IDLE loop. Just sit and loop forever:	
	for(;;) BackTicker++;
}


interrupt void ControlLoop1(void)
{

// Verifying the ISR
    IsrTicker++;

// ***************** LEVEL1 *****************
#if (BUILDLEVEL==LEVEL1)


// -----------------------------------------------------------------------------
//    Call ADC update function.
// -----------------------------------------------------------------------------
	  adc1.update(&adc1);

// -----------------------------------------------------------------------------
//    Call the MICROSTEP_Update function to perform the runtime tasks of the 
//     MICROSTEP_Update algorithm.
// -----------------------------------------------------------------------------
      motor1.Ref.Ipeak = _IQ(IpeakRef);
      motor1.Ref.Spd = _IQ(SpeedRef);
      motor1.Fdb.Ia = _IQ15toIQ((long)adc1.Ch1Out);
      motor1.Fdb.Ib = _IQ15toIQ((long)adc1.Ch2Out);
      MICROSTEP_Update(&motor1); 

// -----------------------------------------------------------------------------
//    Call PWM update function.
// -----------------------------------------------------------------------------
       pwm1.DutyFunc_A = (int16)_IQtoIQ15(motor1.Vref.SinDisc);
       pwm1.DutyFunc_B = (int16)_IQtoIQ15(motor1.Vref.CosDisc);
       pwm1.SinMod_update(&pwm1);

// ------------------------------------------------------------------------------
//    Connect inputs of the DATALOG module 
// ------------------------------------------------------------------------------
       DlogCh1 = (int)_IQtoIQ15(motor1.AngGen.AngleOut);
       DlogCh2 = (int)_IQtoIQ15(motor1.Zoh_Ang.SignalOut);
       DlogCh3 = (int)_IQtoIQ15(_IQsinPU(motor1.AngGen.AngleOut));
       DlogCh4 = (int)_IQtoIQ15(_IQsinPU(motor1.Zoh_Ang.SignalOut));

#endif // (BUILDLEVEL==LEVEL1)


// ------------------------------------------------------------------------------
//    Call the DATALOG update function.
// ------------------------------------------------------------------------------
    dlog.update(&dlog);

// Enable more interrupts from this timer
	EPwm1Regs.ETCLR.bit.INT = 1;

// Acknowledge interrupt to recieve more interrupts from PIE group 3
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

}

//===========================================================================
// No more.
//===========================================================================
