#include "f28x_project.h"
#include "Cla_Support.h"
#include "Solar_CLA.h"
#include "tvmgen_default.h"
#include "stdint.h"

interrupt void Timer0(void);
interrupt void ADC_EOC(void);
interrupt void Cla1_isr(void);

extern unsigned int  RamfuncsLoadStart;
extern unsigned int  RamfuncsLoadEnd;
extern unsigned int  RamfuncsRunStart;

struct tvmgen_default_inputs inputs;
struct tvmgen_default_outputs outputs;

char input_buffer[256],output_buff;

void Timerinit(void);
void GpioInit(void);
void PWMinit(void);
void ADCinit(void);
void CLAinit(void);

#pragma DATA_SECTION(claResult,"Cla1ToCpuMsgRAM");
float32_t claResult;

#pragma DATA_SECTION(clarke1,"Cla1ToCpuMsgRAM");
CLARKE_CLA clarke1;

int m,i,a,cla_is,adc=0;

void main(void)
{

    InitSysCtrl();
    InitGpio();
    TI_NPU_init();
    DINT;

    InitPieCtrl();
    InitFlash();
    IER = 0x0000;
    IFR = 0x0000;

    InitPieVectTable();
    Timerinit();
    GpioInit();
    PWMinit();
    ADCinit();
    CLAinit();



    EALLOW;
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (Uint32)&RamfuncsLoadSize);


    PieCtrlRegs.PIEIER1.bit.INTx7=1;
    PieCtrlRegs.PIEIER1.bit.INTx1=1;
    PieCtrlRegs.PIEIER11.bit.INTx1=1;

    PieVectTable.TIMER0_INT= &Timer0;
    PieVectTable.ADCA1_INT= &ADC_EOC;
    PieVectTable.CLA1_1_INT=&Cla1_isr;

    PieCtrlRegs.PIECTRL.bit.ENPIE= 1;

    IER |=1025;
    EDIS;

    EINT;  // Enable Global interrupt INTM
    ERTM;  // Enable Global realtime interrupt DBGM

    CpuTimer0Regs.TCR.bit.TSS=0;
    while(1)
    {
        for(m = 0; m < 256;m++)
        {
            input_buffer[m] = 2;
            inputs.onnx__Add_0 = input_buffer;
        }

       tvmgen_default_run(&inputs, &outputs);

    }
}


#pragma CODE_SECTION(Cla1_isr, ".TI.ramfunc")

interrupt void Cla1_isr(void)
{
    cla_is=cla_is+1;
    if(cla_is>10)
    {
        cla_is=0;
    }



    PieCtrlRegs.PIEACK.all= PIEACK_GROUP11;
}
#pragma CODE_SECTION(Timer0, ".TI.ramfunc")
interrupt void Timer0(void)
{


    i=i+1;
    if(i>10)
    {
        i=0;
    }


    GpioDataRegs.GPATOGGLE.bit.GPIO20=1;
    GpioDataRegs.GPATOGGLE.bit.GPIO21=1;
    CpuTimer0Regs.TCR.bit.TIF = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;


}

#pragma CODE_SECTION(ADC_EOC, ".TI.ramfunc")
interrupt void ADC_EOC(void)
{

    adc= adc +1;
    if(adc>9)
    {
        adc = 0;
    }
    a= AdcaResultRegs.ADCRESULT0;
    EPwm1Regs.ETCLR.bit.SOCA = 1;
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

}
void Timerinit(void)
{
    EALLOW;
    CpuTimer0Regs.PRD.bit.LSW = 0xD17F;
    CpuTimer0Regs.PRD.bit.MSW = 0x01F0;
    CpuTimer0Regs.TPR.all = 0;
    CpuTimer0Regs.TPRH.all = 0;
    CpuTimer0Regs.TCR.bit.TSS = 1;             // Stop timer
    CpuTimer0Regs.TCR.bit.TRB = 1;             // Reload timer
    CpuTimer0Regs.TCR.bit.TIE = 1;             // Enable interrupt
    CpuTimer0Regs.TCR.bit.TSS = 0;             // Start timer
    EDIS;
}

void GpioInit(void)
{
    EALLOW;
    //LED4
    GpioCtrlRegs.GPAMUX2.bit.GPIO20=0;
    GpioCtrlRegs.GPADIR.bit.GPIO20 = 1;     // Set as output
    GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0;     // Enable pull-up
    GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0;    // Set as GPIO
    GpioDataRegs.GPADAT.bit.GPIO20 = 0;     // Turn ON LED4

    //LED5
    GpioCtrlRegs.GPAMUX2.bit.GPIO21=0;
    GpioCtrlRegs.GPADIR.bit.GPIO21 = 1;     // Set as output
    GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0;     // Enable pull-up
    GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0;    // Set as GPIO
    GpioDataRegs.GPADAT.bit.GPIO21 = 0;     // Turn ON LED5

    EDIS;
}

void PWMinit(void)
{
    EALLOW;
    EPwm1Regs.TBCTL.bit.CTRMODE = 2;             // UP DOWN
    EPwm1Regs.TBPRD = 15000;                    // Set timer period
    EPwm1Regs.TBCTL.bit.PHSEN = 0;               // 1 for external SYNC
    EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;          // Phase is 0
    EPwm1Regs.TBCTR = 0x0000;                    // Clear counter
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;           // Clock ratio to SYSCLKOUT
    EPwm1Regs.TBCTL.bit.CLKDIV = 0;
    EPwm1Regs.EPWMSYNCINSEL.bit.SEL = 0;
    // Setup shadow register load on ZERO
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = 0;
    EPwm1Regs.CMPCTL.bit.LOADBMODE = 0;
    // Set Compare values
          // Set compare A value
    // Set actions
    EPwm1Regs.AQCTLA.all = 0;
    EPwm1Regs.AQCTLA.bit.CAU = 2;                // Set PWM1A on TBCTR = CMPA
    EPwm1Regs.AQCTLA.bit.CAD = 1;                // Clear PWM1A on TBCTR =CMPA


    //SOCA to ADC
    EPwm1Regs.ETSEL.bit.SOCAEN=1;
    EPwm1Regs.ETSEL.bit.SOCASEL=1;
    EPwm1Regs.ETPS.bit.SOCAPRD = 1;
    EPwm1Regs.ETCLR.bit.SOCA = 1;

    EPwm1Regs.CMPA.bit.CMPA= 7500;
    EDIS;
}

void ADCinit(void)
{
    EALLOW;
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS=1;
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ=1;
    AdcaRegs.ADCCTL2.bit.PRESCALE=6;

    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;  //SOC0 will convert pin A0
    AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;  //SOC1 will convert pin A1
    AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2;  //SOC2 will convert pin A2
    AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC3 will convert pin A3
    AdcaRegs.ADCSOC4CTL.bit.CHSEL = 4;  //SOC4 will convert pin A4
    AdcaRegs.ADCSOC5CTL.bit.CHSEL = 5;  //SOC5 will convert pin A5

    AdcaRegs.ADCSOC0CTL.bit.ACQPS = 14; //sample window is 100 SYSCLK cycles
    AdcaRegs.ADCSOC1CTL.bit.ACQPS = 14; //sample window is 100 SYSCLK cycles
    AdcaRegs.ADCSOC2CTL.bit.ACQPS = 14; //sample window is 100 SYSCLK cycles
    AdcaRegs.ADCSOC3CTL.bit.ACQPS = 14; //sample window is 100 SYSCLK cycles
    AdcaRegs.ADCSOC4CTL.bit.ACQPS = 14; //sample window is 100 SYSCLK cycles
    AdcaRegs.ADCSOC5CTL.bit.ACQPS = 14; //sample window is 100 SYSCLK cycles

    AdcaRegs.ADCBURSTCTL.bit.BURSTEN = 1;
    AdcaRegs.ADCBURSTCTL.bit.BURSTSIZE = 11;
    AdcaRegs.ADCBURSTCTL.bit.BURSTTRIGSEL = 5;

    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;
    AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 05;

    EDIS;

}

void CLAinit(void)
{

        extern uint32_t Cla1ProgRunStart, Cla1ProgLoadStart, Cla1ProgLoadSize;

        memcpy((uint32_t *)&Cla1ProgRunStart, (uint32_t *)&Cla1ProgLoadStart,(uint32_t)&Cla1ProgLoadSize);

        EALLOW;
        MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS0 = 1U;
        MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS1 = 0U;
        MemCfgRegs.LSxCLAPGM.bit.CLAPGM_LS2 = 0U;

        //
        // Select CLA as the master of RAMLS0, RAMSL1, RAMLS2
        //
        MemCfgRegs.LSxMSEL.bit.MSEL_LS0 = 1U;
        MemCfgRegs.LSxMSEL.bit.MSEL_LS1 = 1U;
        MemCfgRegs.LSxMSEL.bit.MSEL_LS2 = 1U;

        Cla1Regs.MVECT1 = (uint16_t)(&Cla1Task1);
 //     Cla1Regs.MVECT8 = (uint16_t)(&Cla1Task8);

        DmaClaSrcSelRegs.CLA1TASKSRCSEL1.bit.TASK1 = 01; //ADCAINT1


        DmaClaSrcSelRegs.CLA1TASKSRCSELLOCK.bit.CLA1TASKSRCSEL1 = 0;     // Write a 1 to lock (cannot be cleared once set)
        DmaClaSrcSelRegs.CLA1TASKSRCSELLOCK.bit.CLA1TASKSRCSEL2 = 0;     // Write a 1 to lock (cannot be cleared once set)


        Cla1Regs.MCTL.bit.IACKE = 1;        // Enable IACKE to start task using software
        Cla1Regs.MIER.bit.INT1 = 1;            // Enable CLA interrupt 1
        EDIS;
}

