/****************************************************************************\
 *           Copyright (C) 2013 Texas Instruments Incorporated.             *
 *                           All Rights Reserved                            *
 *                                                                          *
 * GENERAL DISCLAIMER                                                       *
 * ------------------                                                       *
 * All software and related documentation is provided "AS IS" and without   *
 * warranty or support of any kind and Texas Instruments expressly disclaims*
 * all other warranties, express or implied, including, but not limited to, *
 * the implied warranties of merchantability and fitness for a particular   *
 * purpose.  Under no circumstances shall Texas Instruments be liable for   *
 * any incidental, special or consequential damages that result from the    *
 * use or inability to use the software or related documentation, even if   *
 * Texas Instruments has been advised of the liability.                     *
 ****************************************************************************
This example shows three main features of Timers on KeyStone DSP:
1. generate one-shot pulse and interrupt
2. generate continual clock and interrupts
3. watch-dog


***************************************************************************/
#include <c6x.h>
#include <stdio.h>
#include <csl_bootcfgAux.h>
#include "K2_common.h"
#include "K2_Board_Init.h"

/*delay (in millisecond) before the timer generate one-shot pulse*/
#define PULSE_DELAY_MS 			2000
/*period (in millisecond) of the clock generated by timer*/
#define CLOCK_PERIOD_MS 		1
/*number of the clocks generated in this test*/
#define NUM_CLOCKS_GENERATED 	500
/*period (in millisecond) of the watch-dog timer*/
#define WATCH_DOG_PERIOD_MS 	3000

/*since the timer runs at (DSP core clock)/6
the conversion between millisecond and timer PRD value is:
PRD = (xxx_MS/1000)*DSP_CLK_HZ/6
    = xxx_MS*(DSP_CLK_HZ/1000)/6
    = xxx_MS*DSP_CLK_KHZ/6*/
    
volatile Uint32 uiTick = 0;

void Interrupts_Init(void)
{
	gCGEM_Regs->INTMUX1 = 0;
	gCGEM_Regs->INTMUX2 = 0;
	//map local timer interrupt to INT14
	//gCGEM_Regs->INTMUX3 = 0;//CSL_C66X_COREPAC_TIMER_N_INTL<<CSL_CGEM_INTMUX3_INTSEL14_SHIFT;
	gCGEM_Regs->INTMUX3 = CSL_C66X_COREPAC_IPC_GRN << CSL_CGEM_INTMUX3_INTSEL14_SHIFT;

	 /*Clear all DSP core events*/
	gCGEM_Regs->EVTCLR[0]= 	0xFFFFFFFF;
	gCGEM_Regs->EVTCLR[1]= 	0xFFFFFFFF;
	gCGEM_Regs->EVTCLR[2]= 	0xFFFFFFFF;
	gCGEM_Regs->EVTCLR[3]= 	0xFFFFFFFF;

	//clear DSP core interrupt flag
	ICR= IFR;

	//enable INT14
	IER = IER|(1<<14);

	/*Interrupt Service Table Pointer to begining of LL2 memory*/
	ISTP= 0x800000;

	//enable GIE
	TSR = TSR|1;
}

//Interrupt service routine for timer
void interrupt Interrupt_ISR(void)
{
	if((*((unsigned int *)0x02620240))>>4 == 0x5A)	// Check the IPCGR0 whether the interrupt source tag is from ARM Core0
	{
		uiTick++;
		*((unsigned int *)0x02620280) = 0x5A<<4;	// Clear the acknowledge in IPCAR0
	}
    printf("Received interrupt from ARM Core0!\n");
}


void main()
{
	CSL_BootCfgUnlockKicker();

	//DSP core speed= MAIN_PLL_REF_CLK_MHZ*MAIN_PLL_MULTIPLIER/MAIN_PLL_DIVISOR
	KeyStone_main_PLL_init(MAIN_PLL_REF_CLK_MHZ, MAIN_PLL_MULTIPLIER, MAIN_PLL_DIVISOR);

	Interrupts_Init();

	printf("Waiting for interrupt from ARM Core0!\n");

    while(uiTick == 0);

    printf("Trigger the IPCGR8 to generate the interrupt to ARM Core0!\n");

	*((unsigned int *)0x02620260) = (0xFF<<4)|0x1;  // Set tag = 0xFF and Trigger the IPCGR8 to ARM Core0

	while(1);
}

