/* * Blackfin Timer Driven Profiling Example * * Copyright (C) 2003 * by Green Hills Software Inc. * * This program is the property of Green Hills Software, Inc, * its contents are proprietary information and no part of it * is to be disclosed to anyone except employees of Green Hills * Software, Inc., or as agreed in writing signed by the President * of Green Hills Software, Inc. */ #include /* These defines are missing from some Analog header files */ #ifndef PLL_CTL #define PLL_CTL (0xffc00000) #endif #ifndef PLL_DIV #define PLL_DIV (0xffc00004) #endif #ifndef pPLL_CTL #define pPLL_CTL ((volatile unsigned short *)PLL_CTL) #endif #ifndef pPLL_DIV #define pPLL_DIV ((volatile unsigned short *)PLL_DIV) #endif /* This should be set to CLKIN - assume 27MHz, which is what the ADSP-BF533 EZ-KIT Lite has. */ #define INPUT_CLOCK (27000000) /* Number of cycles between each counter decrement */ #define TICK_RATE (16) /* Return the number of times the count register is decremented per second. On Blackfin, calculate by reading PLL_CTL and having CLKIN defined above. This is implemented as described in Chapter 8 of the ADSP-BF533 Blackfin Processor Specification. Note that other Blackfin processors may differ slightly. */ int TICKS_PER_SEC(void) { short pll_ctl = *pPLL_CTL; int csel = ((*pPLL_DIV) >> 4) & 3; int clock = INPUT_CLOCK; /* Initialize clock to CLKIN */ int msel = (pll_ctl >> 9) & 0x3f; if (msel == 0) /* MSEL of 0 has special meaning */ msel = 64; clock *= msel; /* Divide clock by DF */ clock >>= (pll_ctl & 1); /* clock is now VCO, so shift by CSEL to get CCLK */ clock >>= csel; /* TICKS_PER_SEC is CCLK (clock) divided by TCOUNT + 1 */ return clock / TICK_RATE; } /* Initialize the count and compare registers. */ void TIMER_INIT(unsigned int compare) { /* Setup TCOUNT */ *pTCOUNT = compare; } /* Enable the timer interrupt */ void ENABLE_TIMER_INTERRUPT(void) { /* Set TMPWR to turn on power to the timer. */ *pTCNTL = 1; /* Setup the event vector */ *pEVT6 = (void *) __ghs_manprf_timer_handler; /* Enable the core timer interrupt */ *pIMASK |= (1 << 6); /* Decrement TCOUNT every TICK_RATE cycles */ *pTSCALE = TICK_RATE - 1; /* Ensure all those writes had time to take effect */ __CSYNC(); /* Start the timer */ *pTCNTL = 3; } /* Read the exception PC. */ asm unsigned int GET_EPC(void) { /* move from reti */ r0 = reti; } /* Clear the timer interrupt. */ void CLEAR_TIMER_INTERRUPT(void) { /* Restart the timer, clear TINT */ *pTCNTL = 3; __CSYNC(); }