#include "DSP281x_Examples.h"   // DSP281x Examples Include File
#include "DSP281x_Device.h"     // DSP281x Headerfile Include File


#include <f281xpwm.h>
#include <params.h>
#include <project.h>
#include <PWMTMSHandle.h>
#include <PWMTools.h>
#include <v_pwm24_v2.h>

#include "CAN_Setup.h"
#include "global_time.h"
#include "RS_Functions.h"



int  
	m_PWM = 1,	/* 1-ØÈÌ çàêðûò, 0-ØÈÌ îòêðûò */
	Dpwm = 12500, 
	Fpwm = 1000, 
	Dpwm2 = 6250,
    Dpwm4 = 3125,
    Zpwm  = 1; // äåëèòåëü
//TODO èñïðàâèòü ëîãè÷åñêèé êîñßê
static int mPWM_a = 0, mPWM_b = 0;	//ØÈÌ îáìîòêè à è b 1 - âêë., 0 - âûêë. 

PWMGEND pwmd = PWMGEND_DEFAULTS;


#if (TMSPWMGEN==1)

#define DMIN    750 // 15mks Dminimum

interrupt void PWM_Handler(void)
{ 
             
//  static unsigned int time_tick_sec_mks=0;
   static unsigned int pwm_run=0;

   // Enable more interrupts from this timer
   EvaRegs.EVAIMRA.bit.T1PINT = 1;

   // Note: To be safe, use a mask value to write to the entire
   // EVAIFRA register.  Writing to one bit will cause a read-modify-write
   // operation that may have the result of writing 1's to clear 
   // bits other then those intended. 
   EvaRegs.EVAIFRA.all = BIT7;

   // Acknowledge interrupt to receive more interrupts from PIE group 2
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP2;



  // PWM_ticks++;
    
   if (pwm_run==1) 
   {
//	 stop_pwm();
   }
   else
   {

   pwm_run=1;


   EnableInterrupts();
     

 //  if (time_tick_sec_mks>FREQ_PWM)
//   {
//     time_tick_sec++;
//	 time_tick_sec_mks=0;
 //  }
//   else
 //   time_tick_sec_mks++;

 //  rs_a.time_wait_rs_out++;
//   rs_b.time_wait_rs_out++;
 //  rs_a.time_wait_rs_out_mpu++;
//   rs_b.time_wait_rs_out_mpu++;


   global_time.calc(&global_time);
   inc_RS_timeout_cicle();
   inc_CAN_timeout_cicle();

//   led1_on_off(1);
   PWM_interrupt();		/* Âûçîâ ôóíêöèè óïðàâëåíèy ØÈÌîì	*/
//   led1_on_off(0);

   pwm_run=0;

   }
/*
   // Enable more interrupts from this timer
   EvaRegs.EVAIMRA.bit.T1PINT = 1;

   // Note: To be safe, use a mask value to write to the entire
   // EVAIFRA register.  Writing to one bit will cause a read-modify-write
   // operation that may have the result of writing 1's to clear 
   // bits other then those intended. 
   EvaRegs.EVAIFRA.all = BIT7;

   // Acknowledge interrupt to receive more interrupts from PIE group 2
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP2;
   
*/

//   led2_on_off(0);
//   disable();			/* çàïðåùàåì ïðåðûâàíèy TMS			*/


//   SCIb_RX_Int_enable();
//   SCIa_RX_Int_enable();

   
 
} 
#endif


#if (TMSPWMGEN==1)
void init_eva_evb()
{

//   unsigned int tload;

//   stop_pwm();

   EALLOW;

// EVA Configure T1PWM, T2PWM, PWM1-PWM6 
// Initalize the timers
   // Initalize EVA Timer1


  PieVectTable.T1PINT=&PWM_Handler;
  

  EvaRegs.EVAIMRA.bit.T1PINT = 1;
  EvaRegs.EVAIFRA.bit.T1PINT = 1;
  // Enable PIE group 2 interrupt 4 for T1PINT
  PieCtrlRegs.PIEIER2.bit.INTx4 = 1;


//  EvaRegs.EVAIFRA.bit.T1OFINT=1;
//  PieVectTable.T1OFINT = &PWM_Handler2;
//  EvaRegs.EVAIMRA.bit.T1OFINT = 1;
//  EvaRegs.EVAIFRA.bit.T1OFINT = 1;
  // Enable PIE group 2 interrupt 7 for T1PINT
//  PieCtrlRegs.PIEIER2.bit.INTx7 = 1;


//#ifdef DOUBLE_UPDATE_PWM

//  PieVectTable.T1UFINT = &PWM_Handler2;
//  EvaRegs.EVAIMRA.bit.T1UFINT = 1;
//  EvaRegs.EVAIFRA.bit.T1UFINT = 1;

  // Enable PIE group 2 interrupt 7 for T1PINT
//  PieCtrlRegs.PIEIER2.bit.INTx6 = 1;

//#endif


//  EvaRegs.EVAIFRA.bit.T1CINT=1;
//  PieVectTable.T1CINT = &PWM_Handler2;
//  EvaRegs.EVAIMRA.bit.T1CINT = 1;
//  EvaRegs.EVAIFRA.bit.T1CINT = 1;
  // Enable PIE group 2 interrupt 7 for T1PINT
//  PieCtrlRegs.PIEIER2.bit.INTx5 = 1;


  IER |= M_INT2;

  EDIS;
//  start_pwm();


} 
#endif


#if (TMSPWMGEN==1)
void setup_tms_pwm_int(int pwm_freq, int one_two, int pwm_protect)
{
 

  float64	pwm_period;
//  		pwm_tick;
  		        
//  int prev_interrupt;
     
  	//	init_vector();                                           
                                                
//        f_disable();												/* çàïðåùàåì ïðåðûâàíèy TMS */                         
//        *(int *)(VECT_TABLE + VECT_INT2) = (int)PWM_Handler;	/* óñòàíàâëèâàåì îáðàáîò÷èê */
//        SET_IEMASK_INT2();										/* Ìàñêà íà ïðåðûâàíèy */
        
        pwm_period = (float64)HSPCLK/(float64)pwm_freq/2.0;
                
        Fpwm = (int)pwm_freq;
        Dpwm = (int)pwm_period;
        Dpwm2 = (int)(pwm_period/2);
        Dpwm4 = (int)(pwm_period/4);
              
   //     stop_pwm();								/* Çàïðåùåíèå âûõîäîâ ØÈÌ 		*/
  //      setup_pwm_out();




        init_eva_evb();




    EvbRegs.EVBIFRA.bit.PDPINTB=1;
	EvaRegs.EVAIFRA.bit.PDPINTA=1;

//    EVBIFRB
   // Initialize PWM module
	pwmd.PeriodMax = Dpwm;  // Perscaler X1 (T1), ISR period = T x 1
	pwmd.PeriodMin = DMIN;  // Perscaler X1 (T1), ISR period = T x 1

//	ARpwmd.PeriodMax = Dpwm;
//	ARpwmd.PeriodMin = DMIN;
//
	pwmd.ShiftPhaseA = 0;//Dpwm/6.0;
	pwmd.ShiftPhaseB = 0;
		
 	pwmd.init(&pwmd);

//	ARpwmd.init(&pwmd);
  //	m.m2.bit.WDog_pwm = 0;



/*  pwm1.PeriodMax = Dpwm;  // Perscaler X1 (T1), ISR period = T x 1
 	pwm1.init(&pwm1); 

    pwm2.PeriodMax = Dpwm;  // Perscaler X1 (T1), ISR period = T x 1
 	pwm2.init(&pwm2); */


//        if(one_two < 1.5) one_two = 0;
//        if(one_two > 1.5) one_two = 0x80000000;


//        addr_xilinx(WG_COUNT) =  pwm_divisor;	/* Äåëèòåëü ÷àñòîòû ØÈÌà		*/
//        addr_xilinx(WG_PERIOD) = Dpwm<<16;		/* Ïåðèîä ØÈÌ					*/
//        addr_xilinx(ADR_INT) =  one_two;		/* Ïðåðûâàíèé çà ïåðèîä			*/
//        addr_xilinx(WG_PROTECT) = pwm_protect; 	/* Ðàçðåøåíèå áëîêèðîâêè ØÈÌ	*/
    
    
 
//Invoking the computation function 
//svgen_mf1.

// Initialize the SVGEN_MF module
/*
 	svgen_mf1.FreqMax = _IQ(6*BASE_FREQ*T);
 	svgen_mf2.FreqMax = _IQ(6*BASE_FREQ*T);


    svgen_mf2.Offset=_IQ(0);
    svgen_mf1.Offset=_IQ(0);

	svgen_mf1.Alpha = _IQ(0);
    svgen_mf2.Alpha = _IQ(0.52359877559829887307710723054658);


    k=0.1; //0.9;
    freq = 0.499;

*/
//svgen_mf1.calc(&svgen_mf1); 
//svgen_mf2.calc(&svgen_mf2); 
            
//   start_pwm_a();
//   start_pwm_b();


		i_WriteMemory(ADR_PWM_DRIVE_MODE, 0x0000); //Âûáèðàåì â êà÷åñòâå èñòî÷íèêà ØÈÌ TMS

}
#endif

/********************************************************************/
/*         Ðàçðåøåíèå âûõîäîâ ØÈÌà                                                                      */
/********************************************************************/
void start_tms_pwm_a()
{
	unsigned int mask_tk_lines;
	mPWM_a = 1;


    EALLOW;
    EvaRegs.COMCONA.all = 0xa600;//0xA600;             // Init COMCONA Register

    EvaRegs.ACTRA.all = 0x0999;
    EDIS;


}
                                                      
void start_tms_pwm_b()
{
	unsigned int mask_tk_lines;
    mPWM_b = 1;


    EALLOW;
    EvbRegs.COMCONB.all = 0xa600;//0xA600;             // Init COMCONA Register

    EvbRegs.ACTRB.all = 0x0999;
    EDIS;



}                                                     



void start_tms_pwm(void)
{
	mPWM_a = 1;
	mPWM_b = 1;


	m_PWM = 0;
	// m.m1.bit.PWM=0;
	//  m.m1.bit.PWM_A=0;
	//  m.m1.bit.PWM_B=0;

	EALLOW;
	//   addr_xilinx(WG_OUT)=0x00;   

	EvaRegs.COMCONA.all = 0xa600;//0xA600;             // Init COMCONA Register
	EvbRegs.COMCONB.all = 0xa600;//0xA600;             // Init COMCONA Register
  
    EvaRegs.ACTRA.all = 0x0999;
    EvbRegs.ACTRB.all = 0x0999;
          
//   EvaRegs.GPTCONA.bit.TCMPOE=0;
//   EvbRegs.GPTCONB.bit.TCMPOE=0;
//   EvaRegs.T1CON.bit.TECMPR=1;
//   EvbRegs.T3CON.bit.TECMPR=1;
    EDIS;

}                                                                     

/********************************************************************/
/*         Ðàçðåøåíèå îïðåäåëåííûõ âûõîäîâ ØÈÌà                                                                      */
/********************************************************************/
void start_select_tms_pwm(unsigned int mask)
{
  unsigned int mask_pwm_a,mask_pwm_b;
  unsigned char b,i; 


    EALLOW;


       
    EvaRegs.ACTRA.all = 0x0fff;
    EvbRegs.ACTRB.all = 0x0fff;

    EvaRegs.COMCONA.all = 0xa600;//0xA600;             // Init COMCONA Register
    EvbRegs.COMCONB.all = 0xa600;//0xA600;             // Init COMCONA Register


    mask_pwm_a=0;
    for (i=0;i<6;i++)
	{
      b=(mask >> i) & 1;
	  if (b==0) 
	    mask_pwm_a |= (1 << (2*i) );
	  else
	    mask_pwm_a |= (3 << (2*i) );


	}

    mask_pwm_b=0;
    for (i=0;i<6;i++)
	{
      b=(mask >> (i+8)) & 1;
	  if (b==0) 
	    mask_pwm_b |= (1 << (2*i) );
	  else
	    mask_pwm_b |= (3 << (2*i) );

	}

    EvaRegs.ACTRA.all = mask_pwm_a;
    EvbRegs.ACTRB.all = mask_pwm_b;

    EDIS;
}                                                                     


/********************************************************************/            
/*         Çàïðåùåíèå âûõîäîâ ØÈÌà                                                                      */
/********************************************************************/
//#pragma CODE_SECTION(stop_pwm,".fast_run");
void stop_tms_pwm(void)
{
	mPWM_a = 0;
	mPWM_b = 0;


	m_PWM = 1;
	//  m.m1.bit.PWM=1;
	//	m.m1.bit.PWM_A=1;
	//	m.m1.bit.PWM_B=1;

	EALLOW;
	//   EvaRegs.GPTCONA.bit.TCMPOE=1;
	//   EvbRegs.GPTCONB.bit.TCMPOE=1;
	//   EvaRegs.T1CON.bit.TECMPR=0;
	//   EvbRegs.T3CON.bit.TECMPR=0;

	//   addr_xilinx(WG_OUT)=0x0fff;   // Òàêîæäå òîðìîçíîé êëþ÷
	EvaRegs.ACTRA.all = 0x0fff;
	EvbRegs.ACTRB.all = 0x0fff;

	//  EvaRegs.COMCONA.all = 0xa400;//0xA600;             // Init COMCONA Register
	//  EvbRegs.COMCONB.all = 0xa400;//0xA600;             // Init COMCONA Register

	//  EvaRegs.COMCONA.bit.FCMP6OE=0;



	//EvbRegs.COMCONB.bit.FCOMPOE=0;
	//EvaRegs.COMCONA.bit.CENABLE=0;
	//EvbRegs.COMCONB.bit.CENABLE=0;


	EDIS;


}

void stop_tms_pwm_a()
{
	unsigned int mask_tk_lines;            
//    m_PWM = 1;
	mPWM_a = 0;

    EALLOW;
    EvaRegs.ACTRA.all = 0x0fff;
    EDIS;

}


void stop_tms_pwm_b()
{            
    unsigned int mask_tk_lines;
    m_PWM = 1;
	mPWM_b = 0;



    EALLOW;
    EvbRegs.ACTRB.all = 0x0fff;
    EDIS;

}

void setup_tms_pwm_out(void)
{
//int b;
#if (TMSPWMGEN==1)
    EALLOW;

//    GpioMuxRegs.GPDMUX.bit.T3CTRIP_PDPB_GPIOD5=0;
//    GpioMuxRegs.GPDDIR.bit.GPIOD5=0;
//	GpioDataRegs.GPDSET.bit.GPIOD5=1;


//    GpioDataRegs.GPDCLEAR.bit.GPIOD5=1;



    GpioMuxRegs.GPAMUX.bit.PWM1_GPIOA0=1;
	GpioMuxRegs.GPAMUX.bit.PWM2_GPIOA1=1;
	GpioMuxRegs.GPAMUX.bit.PWM3_GPIOA2=1;
	GpioMuxRegs.GPAMUX.bit.PWM4_GPIOA3=1;
	GpioMuxRegs.GPAMUX.bit.PWM5_GPIOA4=1;
	GpioMuxRegs.GPAMUX.bit.PWM6_GPIOA5=1;

    GpioMuxRegs.GPBMUX.bit.PWM7_GPIOB0=1;
	GpioMuxRegs.GPBMUX.bit.PWM8_GPIOB1=1;
	GpioMuxRegs.GPBMUX.bit.PWM9_GPIOB2=1;
	GpioMuxRegs.GPBMUX.bit.PWM10_GPIOB3=1;
	GpioMuxRegs.GPBMUX.bit.PWM11_GPIOB4=1;
	GpioMuxRegs.GPBMUX.bit.PWM12_GPIOB5=1;
 
    EDIS;
    // îòêðûâàåì áóôåðû
//    write_memory(adr_oe_buf_v,0); 
#endif
}