
#include <stdio.h>
#include "csl_gpt.h"
#include "csl_intc.h"
#include <csl_general.h>

#include "csl_uart.h"
#include "csl_uartAux.h"
#include "csl_sysctrl.h"
#include "usbstk5515.h"
#include "usbstk5515_uart.h"

#include "usbstk5515_gpio.h"
#include "usbstk5515_led.h"

#define SARCTRL      ((ioport volatile unsigned*)0x7012)
#define SARDATA      ((ioport volatile unsigned*)0x7014)
#define SARCLKCTRL   ((ioport volatile unsigned*)0x7016)
#define SARPINCTRL   ((ioport volatile unsigned*)0x7018)
#define SARGPOCTRL   ((ioport volatile unsigned*)0x701A)

#define SYS_PCGCR1         *(volatile ioport Uint16*)(0x1c02)
#define SYS_PCGCR2         *(volatile ioport Uint16*)(0x1c03)



#define WR_STR_LEN    (80u)
#define RD_STR_LEN    (10u)

#define CSL_PLL_DIV_000    (0)
#define CSL_PLL_DIV_001    (1u)
#define CSL_PLL_DIV_002    (2u)
#define CSL_PLL_DIV_003    (3u)
#define CSL_PLL_DIV_004    (4u)
#define CSL_PLL_DIV_005    (5u)
#define CSL_PLL_DIV_006    (6u)
#define CSL_PLL_DIV_007    (7u)

#define CSL_PLL_CLOCKIN    (32768u)

#define PLL_CNTL1        *(ioport volatile unsigned *)0x1C20
#define PLL_CNTL2        *(ioport volatile unsigned *)0x1C21
#define PLL_CNTL3        *(ioport volatile unsigned *)0x1C22
#define PLL_CNTL4        *(ioport volatile unsigned *)0x1C23


#define CSL_TEST_FAILED    (1u)
#define CSL_TEST_PASSED    (0)



extern void VECSTART(void);
Uint32    cpuCycleCount = 0;
Uint32    sysClk;
volatile Uint16    hitIsr = 0;


int adc_out[65]=0,Tx_data_lsb,Tx_data_msb,i=0,j,count=0,count_int;
int ADC_data[1300];
int adc_single_data=0;
char *str={"\n ADC data :"};
char msg[]={"  "};
char msg1='s';
char *wrbuffer;
char *result;
CSL_Handle    hGpt;

Int32 Read_GPAIN1(void);
void Init_SAR(void);
Int16 EVM5515_UART_open( );
Int16 CSL_gptIntrTest(void);
Uint32 getSysClk(void);
void Send_data(int adc_data);
/**
 *  \brief  GPT Interrupt Service Routine
 *
 *  \param  none
 *
 *  \return none
 */
interrupt void gpt0Isr(void)
{
    hitIsr = TRUE;

    /* Clear Timer Interrupt Aggregation Flag Register (TIAFR) */
    CSL_SYSCTRL_REGS->TIAFR = 0x01;

    //USBSTK5515_ULED_on(4);
    USBSTK5515_ULED_off(3);
    USBSTK5515_waitusec(1000);
    USBSTK5515_ULED_on(3);
    USBSTK5515_waitusec(1000);
    /*for(i=0;msg[i]!='\0';i++)
    {
    while((UART_LSR & 0x60)==0);  // Wait for TX ready
    EVM5515_UART_putChar(msg[i]);    // Write 1 byte

    }*/

    //Send_data(adc_single_data);

    for(i=0;i<100;i++)
    {
    adc_out[i]=Read_GPAIN1();
    }

    // Send_data(adc_out[i]);


    count_int++;
    printf("\nvalue of count= %d\n",count_int);

    IRQ_clear(TINT_EVENT);


}



void main(void)
{


    int i=0;
    SYS_PCGCR1=0; //INIT clock
    SYS_PCGCR2=0; //INIT clock
    SYS_EXBUSSEL = 0x0A00;  // Enable user LEDs on external bus

    //USBSTK5515_GPIO_setDirection( 18, GPIO_OUT );
    USBSTK5515_ULED_init();

    EVM5515_UART_open();
    printf("\nadc testing");

    Init_SAR();

    /*for(j=0;j<20;j++)
    {
        CSL_gptIntrTest();

    }
    while(i!=1240)
    {
    ADC_data[i]=adc_out[i];
    i++;
    }*/
    while(1)
    {
       // printf("the value of i= %d",i);
        CSL_gptIntrTest();

    }



}


void Send_data(int adc_data)
{

    Tx_data_lsb=(adc_data&0xFF);  //lsb
    Tx_data_msb=((adc_data>>8)&0xFF);//msb

    while((UART_LSR & 0x60)==0);  // Wait for TX ready
    EVM5515_UART_putChar(Tx_data_lsb);    // Write 1 byte

    USBSTK5515_waitusec(1000);

    EVM5515_UART_putChar(Tx_data_msb);    // Write 1 byte
    USBSTK5515_waitusec(1000);
}

void Init_SAR(void)
{
    //*SARCTRL    = 0x4000;   //select ch4, GPAIN2
    *SARCTRL    = 0x3400;      // Select AIN3, which is GPAIN1
    *SARCLKCTRL = 0x0031;      // 100/50 = 2MHz
    *SARPINCTRL = 0x7104;   //Bandgap-Based Reference Voltage set to 0.8V.
    *SARGPOCTRL = 0;
    return;
}
Int32 Read_GPAIN1(void)
{
    Int32 val=0;
    Uint16 i;



       //bit15=soc,bit 14 13 12 i.e 011 so ch3 is selected,bit 10=1 for only one conversion.
         // *SARCTRL = 0xB400; //for ch3 single conv
       *SARCTRL = 0xB800; //for ch3 continuous conv
          // *SARCTRL = 0xC000; //ch4 continuous conv

       while(1)
       {
       for(i=0;i<50; i++)
           asm("   nop");
       val = *SARDATA;
       //val=(val/1023);
       if((val&0x8000) == 0)
       {
           break;
       }
       }

    return val;
}
Int16 CSL_gptIntrTest(void)
{

    CSL_Status    status;
    CSL_Config    hwConfig;
    CSL_GptObj    gptObj;
    Uint32        cpuCycleDelta;

    hitIsr   = FALSE;
    status   = 0;

    /* Get the System clock value at which CPU is currently running */
    sysClk = getSysClk();

    /* CPU clock cycles that  are 1% of the sysClk" value */
    cpuCycleDelta = (sysClk/100);

    printf("\n\nCPU clock is running at %ldKHz\n", sysClk);
    printf("Timer Prescaler Divide Value is Set to Divide by 4\n");
    printf("GPT Runs at Rate 1/4 of the CPU System Clock\n");
    printf("GPT Count is Initialized to 1/4 of CPU Clock Cycles per Millisecond\n");
    printf("With Reference to CPU Clock GPT Will Take 1 Millisecond to Count Down the Timer to 0\n");
    printf("So The CPU Should Execute Approximately %ld(±1%%) Clock Cycles ",sysClk);
    printf("From the Starting of the Timer Till the Expiry of the Timer\n\n");

    /* Open the CSL GPT module */
    hGpt = GPT_open (GPT_0, &gptObj, &status);
    if((NULL == hGpt) || (CSL_SOK != status))
    {
        printf("GPT Open Failed\n");
        return (CSL_TEST_FAILED);
    }
    else
    {
        printf("GPT Open Successful\n");
    }

    /* Reset the GPT module */
    status = GPT_reset(hGpt);
    if(CSL_SOK != status)
    {
        printf("GPT Reset Failed\n");
        return (CSL_TEST_FAILED);
    }
    else
    {
        printf("GPT Reset Successful\n");
    }

    /* Clear any pending interrupts */
    IRQ_clearAll();

    /* Disable all the interrupts */
    IRQ_disableAll();

    IRQ_setVecs((Uint32)(&VECSTART));
    IRQ_plug(TINT_EVENT, &gpt0Isr);
    IRQ_enable(TINT_EVENT);

    hwConfig.autoLoad    = GPT_AUTO_ENABLE;
    hwConfig.ctrlTim     = GPT_TIMER_ENABLE;
    hwConfig.preScaleDiv = GPT_PRE_SC_DIV_1;
    //for 1ms
  // hwConfig.prdLow    = (sysClk)/4;
   //hwConfig.prdHigh     = 0x0000;

   hwConfig.prdLow    = (((sysClk)*5)&0xFFFF);
   hwConfig.prdHigh   = (((sysClk)*5)>>16);
    //for 20ms 5*sysclk=5*262000=1310000=13FD30
    //for 1000ms=1sec=250*sysclk=250*262000=65500000=03E77360
    //hwConfig.prdLow      = 0x7360;
    //hwConfig.prdHigh     = 0x03E7;

    /* Configure the GPT module */
    status =  GPT_config(hGpt, &hwConfig);
    if(CSL_SOK != status)
    {
        printf("GPT Config Failed\n");
        return (CSL_TEST_FAILED);
    }
    else
    {
        printf("GPT Config Successful\n");
    }

    /* Enable CPU Interrupts */
    IRQ_globalEnable();

    /* Start the Timer */
    GPT_start(hGpt);

    /* Wait for the timer interrupt */
    /* This loop takes 12 CPU cycles to execute on iteration.
       So the CPU cycles executed after starting the timer till the
       expiry of the timer will be 12*cpuCycleCount. */
    while(hitIsr != TRUE)
    {
        cpuCycleCount++;



    }

    /* Disable the CPU interrupts */
    IRQ_globalDisable();

    /* Clear any pending interrupts */
    IRQ_clearAll();

    /* Disable all the interrupts */
    IRQ_disableAll();

    /* Stop the Timer */
    status = GPT_stop(hGpt);
    if(CSL_SOK != status)
    {
        printf("GPT Stop Failed \n");
        return (CSL_TEST_FAILED);
    }
    else
    {
        printf("GPT Stop Successful\n");
    }

    status = GPT_reset(hGpt);

    /* Display the number of CPU cycles executed */
    printf("\nTimer Count Reached Zero\n");
    cpuCycleCount *= 12;
    printf("\n\nNUMBER OF CPU CYCLES EXECUTED AFTER STARTING THE TIMER TILL THE TIMER EXPIRY: ");
    printf("%ld\n", cpuCycleCount);

    /* Test passes if the "cpuCycles" value is in the range
       ((sysClk) ± (1% of sysClk)) */
    if(((cpuCycleCount - cpuCycleDelta) < sysClk) &&
        ((cpuCycleCount + cpuCycleDelta) > sysClk))
    {
        printf("GPT IS RUNNING AT THE CONFIGURED RATE!\n\n");
    }
    else
    {
        printf("GPT IS NOT RUNNING AT THE CONFIGURED RATE!\n\n");
        return (CSL_TEST_FAILED);
    }

    /* Close The GPT Module */
    status = GPT_close(hGpt);
    if(CSL_SOK != status)
    {
        printf("GPT Close Failed\n");
        return (CSL_TEST_FAILED);
    }

    return (CSL_TEST_PASSED);
}




#if (defined(CHIP_C5505_C5515) || defined(CHIP_C5504_C5514))

Uint32 getSysClk(void)
{
    Bool      pllRDBypass;
    Bool      pllOutDiv;
    Uint32    sysClk;
    Uint16    pllM;
    Uint16    pllRD;
    Uint16    pllOD;

    pllM = CSL_FEXT(CSL_SYSCTRL_REGS->CGCR1, SYS_CGCR1_M);

    pllRD = CSL_FEXT(CSL_SYSCTRL_REGS->CGCR2, SYS_CGCR2_RDRATIO);
    pllOD = CSL_FEXT(CSL_SYSCTRL_REGS->CGCR4, SYS_CGCR4_ODRATIO);

    pllRDBypass = CSL_FEXT(CSL_SYSCTRL_REGS->CGCR2, SYS_CGCR2_RDBYPASS);
    pllOutDiv   = CSL_FEXT(CSL_SYSCTRL_REGS->CGCR4, SYS_CGCR4_OUTDIVEN);

    sysClk = CSL_PLL_CLOCKIN;

    if (0 == pllRDBypass)
    {
        sysClk = sysClk/(pllRD + 4);
    }

    sysClk = (sysClk * (pllM + 4));

    if (1 == pllOutDiv)
    {
        sysClk = sysClk/(pllOD + 1);
    }

    /* Return the value of system clock in KHz */
    return(sysClk/1000);
}

#elif (defined(CHIP_C5517))
Uint32 getSysClk(void)
{
    Uint32    sysClk;
    float    Multiplier;
    Uint16    OD;
    Uint16    OD2;
    Uint16    RD, RefClk;
    Uint32    temp1, temp2, temp3, vco;
    Uint16 DIV;

    temp2 =  PLL_CNTL2;
    temp3 =  (temp2 & 0x8000) <<1 ;
    temp1 = temp3 + PLL_CNTL1;
    Multiplier = temp1/256 +1;
    RD = (PLL_CNTL2 & 0x003F) ;

    RefClk = 12000/(RD+1);

    vco = Multiplier * (Uint32)RefClk;

    OD = (PLL_CNTL4 & 0x7);

    sysClk = vco/(OD+1);

    OD2 = ((PLL_CNTL4 >> 10) & 0x1F) ;

    if (PLL_CNTL3 & 0x8000) // PLL Bypass
        sysClk = RefClk;
    else
        sysClk = vco/(OD+1);

    if ((PLL_CNTL4 & 0x0020) == 0)  /* OutDiv2 */
        sysClk = sysClk / ( 2*(OD2+1));

    /* Return the value of system clock in KHz */
    return(sysClk);
}
#else

Uint32 getSysClk(void)
{
    Bool      pllRDBypass;
    Bool      pllOutDiv;
    Bool      pllOutDiv2;
    Uint32    sysClk;
    Uint16    pllVP;
    Uint16    pllVS;
    Uint16    pllRD;
    Uint16    pllVO;
    Uint16    pllDivider;
    Uint32    pllMultiplier;

    pllVP = CSL_FEXT(CSL_SYSCTRL_REGS->CGCR1, SYS_CGCR1_MH);
    pllVS = CSL_FEXT(CSL_SYSCTRL_REGS->CGCR2, SYS_CGCR2_ML);

    pllRD = CSL_FEXT(CSL_SYSCTRL_REGS->CGCR2, SYS_CGCR2_RDRATIO);
    pllVO = CSL_FEXT(CSL_SYSCTRL_REGS->CGCR4, SYS_CGCR4_ODRATIO);

    pllRDBypass = CSL_FEXT(CSL_SYSCTRL_REGS->CGCR2, SYS_CGCR2_RDBYPASS);
    pllOutDiv   = CSL_FEXT(CSL_SYSCTRL_REGS->CGCR4, SYS_CGCR4_OUTDIVEN);
    pllOutDiv2  = CSL_FEXT(CSL_SYSCTRL_REGS->CGCR4, SYS_CGCR4_OUTDIV2BYPASS);
    pllDivider = ((pllOutDiv2) | (pllOutDiv << 1) | (pllRDBypass << 2));

    pllMultiplier = ((Uint32)CSL_PLL_CLOCKIN * ((pllVP << 2) + pllVS + 4));

    switch(pllDivider)
    {
        case CSL_PLL_DIV_000:
        case CSL_PLL_DIV_001:
            sysClk = pllMultiplier / (pllRD + 4);
        break;

        case CSL_PLL_DIV_002:
            sysClk = pllMultiplier / ((pllRD + 4) * (pllVO + 4) * 2);
        break;

        case CSL_PLL_DIV_003:
            sysClk = pllMultiplier / ((pllRD + 4) * 2);
        break;

        case CSL_PLL_DIV_004:
        case CSL_PLL_DIV_005:
            sysClk = pllMultiplier;
        break;

        case CSL_PLL_DIV_006:
            sysClk = pllMultiplier / ((pllVO + 4) * 2);
        break;

        case CSL_PLL_DIV_007:
            sysClk = pllMultiplier / 2;
        break;
    }

    /* Return the value of system clock in KHz */
    return(sysClk/1000);
}

#endif

