PADK_300MHz.gel
/*
* The StartUp() function is called every time you start
* Code Composer. You can customize this function to
* perform non-target access initialization.
*/
StartUp()
{
}
/*
* The OnTargetConnect() function is called after CCS establishes
* connection to the target. You can customize this function to
* perform target initialization actions
*/
OnTargetConnect()
{
int i;
/* Reset target */
GEL_Reset();
/* Setup PLL */
PADK_PLL_Initialization();
/* Initialize the EMIF */
PADK_init_emif();
/* Display board revision */
DisplayBoardRevision();
/* Flush the L1P cache */
PADK_FlushICache();
}
/*
* This function is called automatically when the 'Reset DSP'
* Menu item is selected .....
*/
OnReset(int nErrorCode)
{
/* Setup PLL */
PADK_PLL_Initialization();
/* Initialize the EMIF */
PADK_init_emif();
/* Flush the L1P cache */
PADK_FlushICache();
/* Disable dMAX Events */
PADK_DisableDmaxEvents();
}
/*
* PADK_FlushCache()
*/
PADK_FlushICache()
{
#define L1PICR 0x20000004
/* Invalidate all lines of the L1P cache (IP bit) */
*(int *)L1PICR = (*(int *)L1PICR | 0x80000000);
/* Disable cache */
CSR = (CSR & ~0x000000E0) | 0x00000080;
}
/*
* PADK_DisableDmaxEvents()
* Disable all dMAX events
*/
PADK_DisableDmaxEvents()
{
#define DEDR 0x60000010
*(int *)DEDR = 0xFFFFFFFF;
}
/*
* OnPreFileLoaded()
* This function is called automatically when the 'Load Program'
* Menu item is selected .....
*/
OnPreFileLoaded()
{
CSR &= ~1;
/* Flush the L1P cache */
PADK_FlushICache();
/* Disable dMAX Events */
PADK_DisableDmaxEvents();
/* Mute Analog Audio Outputs */
*(unsigned *)0x900060E0 &= ~0x400;
/* Clear interrupt enable register */
IER = 0;
/* Clear any pending register */
IFR = 0;
PADK_init_emif();
}
menuitem "Resets";
hotmenu Reset()
{
GEL_Reset();
PADK_init_emif();
}
hotmenu Reset_BreakPts_and_EMIF()
{
GEL_BreakPtReset();
GEL_Reset();
PADK_init_emif();
}
menuitem "PADK Diagnostics";
hotmenu Reload_GEL_file()
{
PADK_init_emif();
DisplayBoardRevision();
}
hotmenu PADK_PLL_Initialization()
{
/* PLL Memory Map */
#define PLLCSR 0x41000100
#define PLLM 0x41000110
#define PLLDIV0 0x41000114
#define PLLDIV1 0x41000118
#define PLLDIV2 0x4100011C
#define PLLDIV3 0x41000120
#define PLLCMD 0x41000138
#define PLLSTAT 0x4100013C
#define PLLALNCTL 0x41000140
#define CFGBRIDGE 0x40000024
/* FOR PLLCSR */
#define PLLENABLE 0x01
#define PLLDISABLE 0x00
#define PLLPWRDN 0x02
#define PLLPWRUP 0x00
#define PLLOSCPWRDN 0x04
#define PLLOSCPWRUP 0x00
#define PLLRESET 0x08
#define PLLRESETRELEASE 0x00
#define PLLSTABLE 0x40
#define PLLUNSTABLE 0x00
/* FOR PLLCMD */
#define PLLGOCLR 0x0000
#define PLLGOSET 0x0001
/* FOR PLLSTAT */
#define PLLGODONE 0x0000
#define PLLGOWAIT 0x0001
/* FOR ALNCTL */
#define PLLALN1 0x0001
#define PLLALN2 0x0002
#define PLLALN3 0x0004
/* FOR PLLDIV0,1,2,3 and OSCDIV1 */
#define DIVENABLED 0x8000
#define DIV1 0x0000
#define DIV2 0x0001
#define DIV3 0x0002
#define DIV4 0x0003
#define DIV5 0x0004
#define DIV6 0x0005
/* FOR PLLM */
#define TIMES12 0x0C
int i;
GEL_TextOut("PLL Initialization\n");
/* NOTE: Steps 1, 2, and 3 are not necessary when the device is coming
out of reset, since by default PLLEN = 0 and PLLRST = 1. They are
shown here, however, for completeness. */
/* 1. In PLLCSR, write PLLEN = 0 (bypass mode) */
*(int *)PLLCSR = PLLDISABLE;
/* 2. Wait 4 cycles of the slowest of PLLOUT or reference clock source (CLKIN or OSCIN) */
for(i=0;i<4;i++);
/* 3. In PLLCSR, write PLLRST = 1 (PLL is reset) */
*(int *)PLLCSR = PLLDISABLE | PLLRESET;
/* 4. If necessary, program PLLDIV0 and PLLM */
/* Clock input is 25.000 MHz */
/* DIV0 - Before PLL(set to/1) */
*(int *)PLLDIV0 = DIVENABLED | DIV1; /* to get 25.000 MHz */
*(int *)PLLM = TIMES12; /* to get 300.000 MHz */
/* 5. If necessary, program PLLDIV1-n. Note that you must apply the GO operation to
change these dividers to new ratios. */
/* DIV1 - After PLL- SYSCLK1 DSP Core */
/* DIV2 - After PLL- SYSCLK2 PERIPHS (Always twice DIV2) */
/* DIV3 - After PLL- SYSCLK3 EMIF CLOCK */
*(int *)PLLDIV1 = DIVENABLED | DIV1; /* CPU 300.000 MHz */
for(i=0;i<8;i++); /* 8 cycle wait state */
*(int *)PLLDIV2 = DIVENABLED | DIV2; /* 1/2 CPU clock */
for(i=0;i<8;i++); /* 8 cycle wait state */
*(int *)PLLDIV3 = DIVENABLED | DIV3; /* EMIF = 1/3 CPU MHz */
/* Enable PLL Align control. */
*(int *)PLLALNCTL = PLLALN1 | PLLALN2 | PLLALN3;
*(int *)PLLCMD = PLLGOSET;
while (*(int *)PLLSTAT == PLLGOWAIT);
*(int *)PLLCMD = PLLGOCLR;
/* 6. Wait for PLL to properly reset */
/* Reset wait time is 125 ns */
/* assuming 25.000 MHz input */
for(i=0;i<4;i++);
/* 7. In PLLCSR, write PLLRST = 0 to bring PLL out of reset */
*(int *)PLLCSR = PLLDISABLE | PLLRESETRELEASE;
/* 8. Wait for PLL to lock */
/* Lock time after changing D0, PLLM, or input clock is 187.5 us */
/* assuming 25.000 MHz input */
for(i=0;i<4688;i++);
/* 9. In PLLCSR, write PLLEN = 1 to enable PLL mode *. */
*(int *)PLLCSR = PLLENABLE | PLLRESETRELEASE;
/* 10. Bridge reset */
*(int *)CFGBRIDGE = 1; /* Assert reset */
for(i=0;i<10;i++);
*(int *)CFGBRIDGE = 0; /* De-assert reset */
}
hotmenu DisplayBoardRevision()
{
#define FPGA_REVISION_ID 0x900060F0
#define REV_FIRM_MASK 0x00F0
#define REV_ID_MASK 0x000F
#define PROD_ID_MASK 0xFF00
/* Emif must be initialized */
GEL_TextOut("Board Revision = %d",,,,, (*(unsigned short *)FPGA_REVISION_ID) >> 8 );
GEL_TextOut(".%d",,,,, (*(unsigned short*)FPGA_REVISION_ID) & 0x000F );
GEL_TextOut(".%d\n",,,,, ((*(unsigned short*)FPGA_REVISION_ID) >> 4) & 0x000F );
}
/*
* Initialize the EMIF
*/
hotmenu PADK_init_emif()
{
int i;
GEL_TextOut("EMIF Initialization\n");
/* Configure the Async memory (FPGA), EM_CS[2] space: */
#define EMIF_AWCCR 0xF0000004
#define EMIF_A1CR 0xF0000010
/* EMIF Asynchronous Wait Cycle Configuration Register */
*(int *)EMIF_AWCCR = ( 0 << 28) // WP0 : Insert wait cycle if AWAIT is low
| (16 << 0); // MEMC : Max extended wait cycles (max = 16*(MEWC+1))
/* EMIF global control register */
*(int *)EMIF_A1CR = ( 0 << 31) // SS : Select WE mode
| ( 1 << 30) // EW : Enable extended wait mode
| ( 0 << 26) // W_SETUP : 10 ns @ 100 MHz
| ( 9 << 20) // W_STROBE : 90 ns @ 100 MHz
| ( 3 << 17) // W_HOLD : 40 ns @ 100 MHz
| ( 0 << 13) // R_SETUP : 10 ns @ 100 MHz
//| ( 8 << 7) // R_STROBE : 90 ns @ 100 MHz
| ( 9 << 7) // R_STROBE : 100 ns @ 100 MHz
| ( 3 << 4) // R_HOLD : 40 ns @ 100 MHz
| ( 0 << 2) // TA : 10 ns @ 100 MHz
| ( 1 << 0); // ASIZE : 16-bit data bus
/* Configure the SDRAM, EM_CS[0] space: */
/* 1. Configure PLL SYSCLK3 (SDRAM clock) */
/* Already configured in PADK_PLL_Initialization() */
/* 2. Program AC timing registers to meet SDRAM spec */
#define EMIF_SDCR 0xF0000008
#define EMIF_SDRCR 0xF000000C
#define EMIF_SDTIMR 0xF0000020
#define EMIF_SDSRETR 0xF000003C
/* Micron 48LC32M16A2TG-75 */
*(int *)EMIF_SDTIMR = ( 6 << 27) // T_RFC : Auto refresh period (66ns)
| ( 1 << 24) // T_RP : Precharge command period (20 ns)
| ( 1 << 20) // T_RCD : Active to read or write delay (20 ns)
| ( 1 << 16) // T_WR : Write recovery time (1 clk + 7.5 ns)
| ( 4 << 12) // T_RAS : Active to precharge command (44 ns)
| ( 6 << 8) // T_RC : Active to active command period (66 ns)
| ( 1 << 4); // T_RRD : Active bank a to active bank b command (15 ns)
*(int *)EMIF_SDSRETR = 6; // T_RFC : Auto refresh period (66ns)
/* 3. Program the Refresh Rate to satisfy the SDRAM power-up constraint */
/* RR > (100 us/8) * fem_CLK = 1250 (0x4E2) */
*(int *)EMIF_SDRCR = 0x000004E2;
/* 4. Program the Control Register to meet SDRAM spec */
*(int *)EMIF_SDCR = ( 0 << 31) // SR : To avoid self refresh state
| ( 0 << 14) // NM : Not narrow (32-bit)
| ( 2 << 9) // CL : 2 clock
| ( 1 << 8) // BIT11_9LOCK : To allow the CL field to be written (legacy)
| ( 2 << 4) // IBANK : 4 internal SDRAM banks
| ( 2 << 0); // PAGESIZE : 1024 word pages
/* 5. Access or wait 200 us in order to allow the EMIF
auto-initialization sequence to complete. */
i = *(int *)(0x80000000);
/* 6. Program the "real" Refresh Rate to match the SDRAM refresh interval. */
/* 64 ms, 4096 cycle refresh rate */
/* RR <= fem_CLK * tRefreshperiod/nCycles = 1562.5
round down to meet the "<" (0x61A) */
*(int *)EMIF_SDRCR = 0x0000061A;
}