
/**
 * \file  timerCounter.c
 *
 * \brief Sample application for timer.
 */

/*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*    Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
*    Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the
*    distribution.
*
*    Neither the name of Texas Instruments Incorporated nor the names of
*    its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "uart.h"
#include "hw_uart.h"
#include "interrupt.h"
#include "soc_C6748.h"
#include "hw_syscfg0_C6748.h"
#include "timer.h"
#include "lcdkC6748.h"
#include "uartStdio.h"
#include "gpio.h"
#include "psc.h"
#include"hw_types.h"

#include "edma_event.h"
#include "edma.h"
#include "spi.h"
#include <stddef.h>
#include <stdio.h>                     /* This ert_main.c example uses printf/fflush */



#ifndef _TMS320C6X
#include "cpu.h"
#endif

/******************************************************************************
**                      INTERNAL MACRO DEFINITIONS
*******************************************************************************/
#define STR_LEN                        (13)
#define TMR_PERIOD_LSB32               (0x000002AF)
//#define TMR_PERIOD_LSB32               (0x00000dfa)

//#define TMR_PERIOD_LSB32               (0x0F424000)
//#define TMR_PERIOD_LSB32               (0x00B71B00)
#define TMR_PERIOD_MSB32               (0x0)

/******************************************************************************
**                      INTERNAL FUNCTION PROTOTYPES
*******************************************************************************/
//static void TimerIsr(void);
static void TimerSetUp64Bit(void);
//static void TimerIntrSetUp(void);

/******************************************************************************
**                      INTERNAL VARIABLE DEFINITIONS
*******************************************************************************/

/******************************************************************************
**                          FUNCTION DEFINITIONS
*******************************************************************************/


#define PINMUX11_GPIO5_8_ENABLE    (SYSCFG_PINMUX11_PINMUX11_31_28_GPIO5_8  << \
                                    SYSCFG_PINMUX11_PINMUX11_31_28_SHIFT)

void  GPIOBank6Pin13PinMuxSetup();

volatile int dummy=0;
volatile int intflag=0;
volatile int flag1=0;

volatile int toggle_val;
static void (*cb_Fxn[EDMA3_NUM_TCC]) (unsigned int tcc, unsigned int status);
static void EDMA3Initialize(void);
static void SetupInt(void);
static void edma3ComplHandler(unsigned int baseAdd, unsigned int regionNum);
static void Edma3ComplHandlerIsr(void);
static void edma3CCErrHandler(unsigned int baseAdd);
static void Edma3CCErrHandlerIsr();
static void ConfigureIntEDMA3(void);
static void callback(unsigned int tccNum, unsigned int status);
static void SPITransmitData(unsigned int tccNum, unsigned int chNum,volatile char*);
void GPIOBank5Pin8PinMuxSetup();

#define EVT_QUEUE_NUM             40

volatile char toggle_val1[4];
volatile char toggle_val2[4];
int i=0;

int main(void)
{
    //HWREG(0x01C11100)|=0x00000001;                          //Enabling PLLCTL
    HWREG(0x01C11100) =0x00000051;
   // HWREG(0x01C11110)=                                                   //PLLM
    HWREG(0x01C11128)= 0x0008000;                                                  //POSTDIV

   //HWREG(0x01e1a100)|=0x00000001;                          //Enabling PLLCTL
  HWREG(0x01e1a100)=0x00000051;
   //HWREG(0x01e1a110)=                                                   //PLLM
   HWREG(0x01e1a128)= 0x0008000;                                         //POSTDIV


toggle_val=0x01000000;

for(i=0;i<4;i++)
     toggle_val1[i]=0xff;

for(i=0;i<4;i++)
     toggle_val2[i]=0xff;


EDMA3Initialize();

/* The Local PSC number for GPIO is 3. GPIO belongs to PSC1 module.*/
        PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON,
                 PSC_MDCTL_NEXT_ENABLE);

        /* Pin Multiplexing of pin 8 of GPIO Bank 5.*/
        GPIOBank5Pin8PinMuxSetup();

        /* Sets the pin 89 (GP6[13]) as output.*/
        GPIODirModeSet(SOC_GPIO_0_REGS, 89, GPIO_DIR_OUTPUT);


    /* Set up the Timer3 peripheral */
    TimerSetUp64Bit();
    /* Enable the timer interrupt */

    TimerIntEnable(SOC_TMR_3_REGS, TMR_INT_TMR12_NON_CAPT_MODE);

    EDMA3RequestChannel(SOC_EDMA31CC_0_REGS , EDMA3_CHANNEL_TYPE_DMA,
                       EDMA3_CHA_TIMER64P3_EVT12, EDMA3_CHA_TIMER64P3_EVT12,
                        EVT_QUEUE_NUM);

    cb_Fxn[EDMA3_CHA_TIMER64P3_EVT12] = &callback;

    SPITransmitData(EDMA3_CHA_TIMER64P3_EVT12,EDMA3_CHA_TIMER64P3_EVT12,toggle_val1);
    /* Set up the AINTC to generate Timer2 interrupts */
 //  TimerIntrSetUp();
  /* Enable the timer interrupt */
 //   TimerIntEnable(SOC_TMR_3_REGS, TMR_INT_TMR12_NON_CAPT_MODE);

#ifndef _TMS320C6X
    /* Switch to non privileged mode; This is done for demonstration purpose */
    CPUSwitchToUserMode();
#endif


    /* Start the timer. Characters from cntArr will be sent from the ISR */




    TimerEnable(SOC_TMR_3_REGS, TMR_TIMER12, TMR_ENABLE_CONT);

//    while (rtmGetErrorStatus(code_total_M) == (NULL)) {
//      /*  Perform other application tasks here */
//    }

    while(1)
    {

        //if(intflag==1)
       // {
        //    for(flag1=0;flag1<5;flag1++);
       //     intflag=0;
        //    TimerIntEnable(SOC_TMR_3_REGS, TMR_INT_TMR12_NON_CAPT_MODE);

       // }

    }

    /* Disable rt_OneStep() here */

    /* Terminate model */



    //TimerDisable(SOC_TMR_3_REGS, TMR_TIMER12);

    /* Halt the program */
    //while(1);
}

/*
** Timer Interrupt Service Routine
*/
static void SPITransmitData(unsigned int tccNum, unsigned int chNum,volatile char*buffer)
{
        EDMA3CCPaRAMEntry paramSet;

        EDMA3CCPaRAMEntry paramSet1;
        EDMA3CCPaRAMEntry paramSet2;

        paramSet1.srcAddr = (unsigned int)buffer;
        paramSet1.destAddr =(unsigned int) &(toggle_val);//0x01e26064;    //gpio_outdata45
        paramSet1.aCnt = (unsigned short)1;
        paramSet1.bCnt = (unsigned short)1;
        paramSet1.cCnt = (unsigned short)1;

       /* The src index should increment for every byte being transferred. */
       paramSet1.srcBIdx = (short) 0u;

       /* The dst index should not be increment since it is a h/w register*/
       paramSet1.destBIdx = (short) 0u;

       /* A sync Transfer Mode */
       paramSet1.srcCIdx = (short) 0u;
       paramSet1.destCIdx = (short) 0u;
       paramSet1.linkAddr = 0x01e34220;
       paramSet1.bCntReload = (unsigned short)0u;
       paramSet1.opt =0x0011a003;
       EDMA3SetPaRAM(SOC_EDMA31CC_0_REGS, 16, &paramSet1);


       paramSet2.srcAddr = (unsigned int)buffer;
       paramSet2.destAddr =(unsigned int) &(toggle_val);    //gpio_outdata45
       paramSet2.aCnt = (unsigned short)1;
       paramSet2.bCnt = (unsigned short)1;
       paramSet2.cCnt = (unsigned short)1;

       /* The src index should increment for every byte being transferred. */
       paramSet2.srcBIdx = (short) 0u;

       /* The dst index should not be increment since it is a h/w register*/
       paramSet2.destBIdx = (short) 0u;

       /* A sync Transfer Mode */
       paramSet2.srcCIdx = (short)0u;
       paramSet2.destCIdx = (short) 0u;
       paramSet2.linkAddr = 0x01e34200;
       paramSet2.bCntReload = (unsigned short)0u;
       paramSet2.opt =0x0011a003;
       EDMA3SetPaRAM(SOC_EDMA31CC_0_REGS, 17, &paramSet2);

        /* Fill the PaRAM Set with transfer specific information */
        paramSet.srcAddr = (unsigned int)buffer;
        paramSet.destAddr = (unsigned int) &(toggle_val);    //gpio_outdata45
        paramSet.aCnt = (unsigned short)1;
        paramSet.bCnt = (unsigned short)1;
        paramSet.cCnt = (unsigned short)1;

        /* The src index should increment for every byte being transferred. */
        paramSet.srcBIdx = (short) 0u;

        /* The dst index should not be increment since it is a h/w register*/
        paramSet.destBIdx = (short) 0u;

        /* A sync Transfer Mode */
        paramSet.srcCIdx = (short) 0u;
        paramSet.destCIdx = (short) 0u;
       paramSet.linkAddr = 0x01e34220;
       paramSet.bCntReload = (unsigned short)0u;
       paramSet.opt =0x0011a003;

        /* Now write the PaRAM Set */
        EDMA3SetPaRAM(SOC_EDMA31CC_0_REGS, chNum, &paramSet);


        EDMA3EnableTransfer(SOC_EDMA31CC_0_REGS, chNum, EDMA3_TRIG_MODE_EVENT);
}


//static void TimerIsr(void)
//{
//    /* Disable the timer interrupt */
//    TimerIntDisable(SOC_TMR_3_REGS, TMR_INT_TMR12_NON_CAPT_MODE);
//   if(dummy==0)
//       dummy=1;
//   else
//       dummy=0;
//    GPIOPinWrite(SOC_GPIO_0_REGS, 89,dummy);
//
//#ifdef _TMS320C6X
//    /* Clear interrupt status in DSPINTC */
//    IntEventClear(SYS_INT_T64P3_TINTALL);
//#else
//    /* Clear the interrupt status in AINTC */
//    IntSystemStatusClear(SYS_INT_TIMR3_ALL);
//#endif
//    TimerIntStatusClear(SOC_TMR_3_REGS, TMR_INT_TMR12_NON_CAPT_MODE);
//
//
//
// // GPIOPinWrite(SOC_GPIO_0_REGS, 89, GPIO_PIN_LOW);
//    /* Enable the timer interrupt */
//  TimerIntEnable(SOC_TMR_3_REGS, TMR_INT_TMR12_NON_CAPT_MODE);
//// intflag=1;
//}


/*
** Setup the timer for 64 bit mode
*/
static void TimerSetUp64Bit(void)
{
    /* Configuration of Timer */
  //  TimerConfigure(SOC_TMR_3_REGS, TMR_CFG_64BIT_CLK_EXT);
   TimerConfigure(SOC_TMR_3_REGS, TMR_CFG_64BIT_CLK_INT );

    /* Set the 64 bit timer period */
    TimerPeriodSet(SOC_TMR_3_REGS, TMR_TIMER12, TMR_PERIOD_LSB32);
    TimerPeriodSet(SOC_TMR_3_REGS, TMR_TIMER34, TMR_PERIOD_MSB32);

   // HWREG(SOC_TMR_3_REGS + 0x20)|=0x02000200;                   //using external clock
}



void GPIOBank5Pin8PinMuxSetup()                 //HEADER J14 PIN 29
{
    unsigned int savePinmux = 0;

    /*
    ** Clearing the bit in context and retaining the other bit values
    ** in PINMUX13 register.
    */
    savePinmux = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(11)) &
    ~(SYSCFG_PINMUX11_PINMUX11_31_28));

    /* Setting the pins corresponding to GP6[13] in PINMUX13 register.*/
    HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(11)) =
    (PINMUX11_GPIO5_8_ENABLE | savePinmux);
}
/***************************** End Of File ***********************************/

/* Function used to Initialize EDMA3 */
static void EDMA3Initialize(void)
{
    /* Enabling the PSC for EDMA3CC_0.*/
    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_CC1, PSC_POWERDOMAIN_ALWAYS_ON,
             PSC_MDCTL_NEXT_ENABLE);

    /* Enabling the PSC for EDMA3TC_0.*/
    PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_TC2, PSC_POWERDOMAIN_ALWAYS_ON,
             PSC_MDCTL_NEXT_ENABLE);

    /* Initialization of EDMA3 */
    EDMA3Init(SOC_EDMA31CC_0_REGS, EVT_QUEUE_NUM);

    /*
    ** Enable AINTC to handle interuppts. Also enable IRQ interuppt in
    ** ARM processor.
    */
    SetupInt();

    /* Register EDMA3 Interrupts */
    ConfigureIntEDMA3();
}

/* Function used to Setup ARM Interuppt Controller */
static void SetupInt(void)
{
#ifdef _TMS320C6X
    // Initialize the DSP Interrupt controller
    IntDSPINTCInit();

    // Enable DSP interrupts globally
    IntGlobalEnable();
#else
    /*Initialize the ARM Interrupt Controller(AINTC). */
    IntAINTCInit();

    /* Enable IRQ in CPSR.*/
    IntMasterIRQEnable();

    /* Enable the interrupts in GER of AINTC.*/
    IntGlobalEnable();

    /* Enable the interrupts in HIER of AINTC.*/
    IntIRQEnable();
#endif
}

/* EDMA3 Completion Handler */
static void edma3ComplHandler(unsigned int baseAdd, unsigned int regionNum)
{
    TimerIntDisable(SOC_TMR_3_REGS, TMR_INT_TMR12_NON_CAPT_MODE);
    volatile unsigned int pendingIrqs;
    volatile unsigned int isIPR = 0;

    unsigned int indexl;
    unsigned int Cnt = 0;
    indexl = 1;

#ifdef _TMS320C6X
    IntEventClear(SYS_INT_EDMA3_1_CC0_INT1);


#else
    IntSystemStatusClear(SYS_INT_CCINT0);
#endif
    isIPR = HWREG(baseAdd + EDMA3CC_S_IPR(regionNum));
    if(isIPR)
    {
       // while ((Cnt < EDMA3CC_COMPL_HANDLER_RETRY_COUNT)&& (indexl != 0u))
        while ((Cnt < 31)&& (indexl != 0u))
        {
            indexl = 0u;
            pendingIrqs = HWREG(baseAdd + EDMA3CC_S_IPR(regionNum));
            while (pendingIrqs)
            {
                if((pendingIrqs & 1u) == TRUE)
                {
                    /**
                    * If the user has not given any callback function
                    * while requesting the TCC, its TCC specific bit
                    * in the IPR register will NOT be cleared.
                    */
                    /* here write to ICR to clear the corresponding IPR bits */
                    HWREG(baseAdd + EDMA3CC_S_ICR(regionNum)) = (1u << indexl);

                    (*cb_Fxn[indexl])(indexl, EDMA3_XFER_COMPLETE);
                }
                ++indexl;
                pendingIrqs >>= 1u;
            }
            Cnt++;
        }
    }
   TimerIntEnable(SOC_TMR_3_REGS, TMR_INT_TMR12_NON_CAPT_MODE);

}





static void Edma3ComplHandlerIsr(void)
{
#ifdef _TMS320C6X
    // Invoke Completion Handler ISR
    edma3ComplHandler(SOC_EDMA31CC_0_REGS, 1);
#else
    /* Invoke Completion Handler ISR */
    edma3ComplHandler(SOC_EDMA31CC_0_REGS, 0);
#endif
}

//static void Edma3ComplHandlerIsr1(void)
//{
//#ifdef _TMS320C6X
//    // Invoke Completion Handler ISR
//    edma3ComplHandler(SOC_EDMA30CC_0_REGS, 2);
//#else
//    /* Invoke Completion Handler ISR */
//    edma3ComplHandler(SOC_EDMA30CC_0_REGS, 0);
//#endif
//}

/* EDMA3 Error Handler */
static void edma3CCErrHandler(unsigned int baseAdd)
{
    volatile unsigned int pendingIrqs = 0;
    unsigned int regionNum = 0;
    unsigned int evtqueNum = 0;
    unsigned int index = 1;
    unsigned int Cnt = 0;

#ifdef _TMS320C6X
    IntEventClear(SYS_INT_EDMA3_1_CC0_ERRINT);
#else
    IntSystemStatusClear(SYS_INT_CCERRINT);
#endif

    if((HWREG(baseAdd + EDMA3CC_EMR) != 0 ) || \
       (HWREG(baseAdd + EDMA3CC_QEMR) != 0) || \
       (HWREG(baseAdd + EDMA3CC_CCERR) != 0))
    {
        /* Loop for EDMA3CC_ERR_HANDLER_RETRY_COUNT number of time, breaks
           when no pending interrupt is found */
        while ((Cnt < EDMA3CC_ERR_HANDLER_RETRY_COUNT) && (index != 0u))
        {
            index = 0u;
            pendingIrqs = HWREG(baseAdd + EDMA3CC_EMR);
            while (pendingIrqs)
            {
                /*Process all the pending interrupts*/
                if((pendingIrqs & 1u)==TRUE)
                {
                    /* Write to EMCR to clear the corresponding EMR bits.*/
                    HWREG(baseAdd + EDMA3CC_EMCR) = (1u<<index);
                    /*Clear any SER*/
                    HWREG(baseAdd + EDMA3CC_S_SECR(regionNum)) = (1u<<index);
                }
                ++index;
                pendingIrqs >>= 1u;
            }
            index = 0u;
            pendingIrqs = HWREG(baseAdd + EDMA3CC_QEMR);
            while (pendingIrqs)
            {
                /*Process all the pending interrupts*/
                if((pendingIrqs & 1u)==TRUE)
                {
                    /* Here write to QEMCR to clear the corresponding QEMR bits*/
                    HWREG(baseAdd + EDMA3CC_QEMCR) = (1u<<index);
                    /*Clear any QSER*/
                    HWREG(baseAdd + EDMA3CC_S_QSECR(0)) = (1u<<index);
                }
                ++index;
                pendingIrqs >>= 1u;
            }
            index = 0u;
            pendingIrqs = HWREG(baseAdd + EDMA3CC_CCERR);
    if (pendingIrqs != 0u)
    {
        /* Process all the pending CC error interrupts. */
        /* Queue threshold error for different event queues.*/
        for (evtqueNum = 0u; evtqueNum < EDMA3_0_NUM_EVTQUE; evtqueNum++)
        {
            if((pendingIrqs & (1u << evtqueNum)) != 0u)
            {
                /* Clear the error interrupt. */
                HWREG(baseAdd + EDMA3CC_CCERRCLR) = (1u << evtqueNum);
            }
         }

         /* Transfer completion code error. */
         if ((pendingIrqs & (1 << EDMA3CC_CCERR_TCCERR_SHIFT)) != 0u)
         {
             HWREG(baseAdd + EDMA3CC_CCERRCLR) = \
                  (0x01u << EDMA3CC_CCERR_TCCERR_SHIFT);
         }
         ++index;
    }
    Cnt++;
        }
    }
}

static void Edma3CCErrHandlerIsr()
{
    /* Invoke CC Error Handler ISR */
    edma3CCErrHandler(SOC_EDMA31CC_0_REGS);
}

/* Function to register EDMA3 Interuppts */
static void ConfigureIntEDMA3(void)
{
    /* Register Interrupts Here */

#ifdef _TMS320C6X
    IntRegister(C674X_MASK_INT4, Edma3ComplHandlerIsr);
    //IntRegister(C674X_MASK_INT6, Edma3ComplHandlerIsr1);
    IntRegister(C674X_MASK_INT5, Edma3CCErrHandlerIsr);
  //  IntRegister(C674X_MASK_INT6, TimerIsr);

    IntEventMap(C674X_MASK_INT4, SYS_INT_EDMA3_1_CC0_INT1);
    //IntEventMap(C674X_MASK_INT6, SYS_INT_EDMA3_0_CC0_INT2);
    IntEventMap(C674X_MASK_INT5, SYS_INT_EDMA3_1_CC0_ERRINT);
  //  IntEventMap(C674X_MASK_INT6, SYS_INT_T64P3_TINTALL);

    IntEnable(C674X_MASK_INT4);
    IntEnable(C674X_MASK_INT5);
 //   IntEnable(C674X_MASK_INT6);

    #else
    IntRegister(SYS_INT_CCINT0, Edma3ComplHandlerIsr);

    IntChannelSet(SYS_INT_CCINT0, 2);

    IntSystemEnable(SYS_INT_CCINT0);

    IntRegister(SYS_INT_CCERRINT, Edma3CCErrHandlerIsr);

    IntChannelSet(SYS_INT_CCERRINT, 2);

    IntSystemEnable(SYS_INT_CCERRINT);
#endif
}


/*
** This function is used as a callback from EDMA3 Completion Handler.
** UART in DMA Mode is Disabled over here.
*/
static void callback(unsigned int tccNum, unsigned int status)
{



}


//static void TimerIsr(void)
//{
//    /* Disable the timer interrupt */
//    TimerIntDisable(SOC_TMR_3_REGS, TMR_INT_TMR12_NON_CAPT_MODE);
//
//
//#ifdef _TMS320C6X
//    /* Clear interrupt status in DSPINTC */
//    IntEventClear(SYS_INT_T64P3_TINTALL);
//#else
//    /* Clear the interrupt status in AINTC */
//    IntSystemStatusClear(SYS_INT_TIMR3_ALL);
//#endif
//    TimerIntStatusClear(SOC_TMR_3_REGS, TMR_INT_TMR12_NON_CAPT_MODE);
//
//
//
// // GPIOPinWrite(SOC_GPIO_0_REGS, 89, GPIO_PIN_LOW);
//    /* Enable the timer interrupt */
//  TimerIntEnable(SOC_TMR_3_REGS, TMR_INT_TMR12_NON_CAPT_MODE);
//
//}
