📄 initfuncs.c
字号:
/*****************************************************************************
File name : initfuncs.c
Description :
Date Modification Initials
---- ------------ --------
13/02/01 Modified the file stm\str1.8\src\cstartup\initfuncs.c BK
02/05/01 Modified according the 5518 overclocking technical note LP
Added support for ST20_CPU_Clock=81 MHz
Added the functions:
static int PLLAlreadyInitialised(void);
static void InitPLLParams(char Mfactor, char Nfactor, char Pfactor);
Changed ROM_ConfigurePLL();
*****************************************************************************/
#include <initfuncs.h>
static void ROM_ConfigurePLL(void);
#pragma ST_nolink(ROM_ConfigurePLL)
static void ROM_ConfigureSDRAM(void);
#pragma ST_nolink(ROM_ConfigureSDRAM)
static int PLLAlreadyInitialised(void);
#pragma ST_nolink(PLLAlreadyInitialised)
static void InitPLLParams(char Mfactor, char Nfactor, char Pfactor);
#pragma ST_nolink(InitPLLParams)
#pragma ST_device(SDU8)
typedef volatile unsigned char SDU8;
/* LP on 22/11/00 - the below section has been added to the original file to enable the support
* of SDRAM + PLL initialization for unified memory config booting from ROM
*/
#define SdramBase 0xC0000000
#define ClockGenBaseAddress 0x00000100
#define VideoBaseAddress 0x00000000
#define SDRAM_CFG_MCF (VideoBaseAddress + 0x00)
#define SDRAM_CFG_CCF (VideoBaseAddress + 0x01)
#define SDRAM_CFG_DRC (VideoBaseAddress + 0x38)
#define SDRAM_VID_LCK (VideoBaseAddress + 0x7B) /* Locks the three previous registers */
#define SDRAM_CKG_CCAUD (ClockGenBaseAddress + 0xD0)
#define SDRAM_CKG_DIVAUD (ClockGenBaseAddress + 0xD1)
#define SDRAM_CKG_CCAUXDENC (ClockGenBaseAddress + 0xD2)
#define SDRAM_CKG_DIVAUXDENC (ClockGenBaseAddress + 0xD3)
#define SDRAM_CKG_CCMCK (ClockGenBaseAddress + 0xD4)
#define SDRAM_CKG_DIVMCK (ClockGenBaseAddress + 0xD5)
#define SDRAM_CKG_KARA1 (ClockGenBaseAddress + 0xDA)
#define SDRAM_CKG_KARA0 (ClockGenBaseAddress + 0xDB)
#define SDRAM_CKG_CCDENC (ClockGenBaseAddress + 0xDC)
#define SDRAM_CKG_CCST20 (ClockGenBaseAddress + 0xDD)
#define SDRAM_CKG_DIVST20 (ClockGenBaseAddress + 0xDE)
#define SDRAM_CKG_PREDIVPLL (ClockGenBaseAddress + 0xDF)
#define SDRAM_CKG_FBKDIVPLL (ClockGenBaseAddress + 0xE0)
#define SDRAM_CKG_POSTDIVPLL (ClockGenBaseAddress + 0xE1)
#define SDRAM_PLLSETUP (ClockGenBaseAddress + 0xE2)
#define SDRAM_CKG_IDDQPAD_C (ClockGenBaseAddress + 0xE3)
#define SDRAM_CKG_AUD_CNT (ClockGenBaseAddress + 0xE8)
#define SDRAM_WRITE_8( address, value ) \
{ \
*((SDU8 *)(address)) = (SDU8) (value); \
}
#define SDRAMClockDivider 2
#define AudioClockDivider 2
#if defined(CPUCLOCK81)
#define ST20ClockDivider 3
#else
#define ST20ClockDivider 4
#endif
/**
* Function to check if the Phase Lock Loop has been initialised or not
* returns 1 if it has and 0 if it hasn't
*/
static int PLLAlreadyInitialised(void)
{
unsigned char tmp;
int beenInit;
/* Test if the PLL has already has been programmed */
beenInit = 0;
/*Will read 0000 if has not been initialised*/
tmp = *(SDU8 *)SDRAM_CFG_DRC;
/*AND with 1111 (0x0F) and if answer isn't 0000, has been initialised*/
/*Why is this not just if (tmp != 0x00)???*/
if ((tmp & 0x0f) != 0x00)
{
/*PLL has been initialised*/
beenInit = 1;
}
return beenInit;
}
static void InitPLLParams(char Mfactor, char Nfactor, char Pfactor)
{
unsigned int n;
/*First write Pfactor = 2*/
SDRAM_WRITE_8(SDRAM_CKG_POSTDIVPLL,(0x02<<5)|0x10);
SDRAM_WRITE_8(SDRAM_CKG_PREDIVPLL,Mfactor);
SDRAM_WRITE_8(SDRAM_CKG_FBKDIVPLL,Nfactor);
for (n=0 ; n<5000 ; n++);
SDRAM_WRITE_8(SDRAM_CKG_CCST20,0x80);
SDRAM_WRITE_8(SDRAM_CKG_POSTDIVPLL,((Pfactor &0x07)<<5)|0x10);
}
static void ROM_ConfigurePLL(void)
{
unsigned int i;
/* Regardless of the CPU frequency the PLL coefficients are calculated for Fpll = 483 MHz */
InitPLLParams(14,126,0);
/* By default, after a hard reset, the ST20/FEI/LINK clock generator is initialised to 60.75 Mhz */
/* => It is not usefull to initialise the ST20/FEI/LINK clock controller register */
/* By default, after a hard reset, the denc clock generator is initialised to 27 Mhz */
/* => It is not usefull to initialise the denc clock controller register */
/*First bypass=true ST20 clock = 27MHz*/
SDRAM_WRITE_8(SDRAM_CKG_CCST20,0x80);
SDRAM_WRITE_8(SDRAM_CKG_DIVST20,((ST20ClockDivider&0xf)<<4));
/* Init SDRAM clock */
SDRAM_WRITE_8(SDRAM_CKG_CCMCK, 0xA0);
SDRAM_WRITE_8(SDRAM_CKG_DIVMCK, ((SDRAMClockDivider&0xf)<<4));
/* Init Audio clock */
SDRAM_WRITE_8(SDRAM_CKG_CCAUD, 0xA0);
SDRAM_WRITE_8(SDRAM_CKG_DIVAUD, ((AudioClockDivider&0xf)<<4));
SDRAM_WRITE_8(SDRAM_CKG_CCST20,0xA0);
SDRAM_WRITE_8(SDRAM_CKG_DIVST20,((ST20ClockDivider&0xf)<<4));
/* The ST20 via the clock generator controls the frequency synthetizer
instead of the MMDS. Hardware bug in the DSP prevents it from monitoring
the frequency synthetizer after the hard reset!
*/
SDRAM_WRITE_8(SDRAM_CKG_AUD_CNT, 0x80);
/* Control Register initialization */
SDRAM_WRITE_8(SDRAM_CFG_CCF, 0xFF);
/* Wait for PLL to stabilise */
for (i=0 ; i<2000 ; i++);
}
static void ROM_ConfigureSDRAM(void)
{
unsigned int ii;
unsigned char Phase;
volatile unsigned long *sdram_pointer = (unsigned long *)0xC0000000;
/* Reset refresh time */
SDRAM_WRITE_8(SDRAM_CFG_MCF, 0x00);
/* Reset SDRAM first ! */
SDRAM_WRITE_8(SDRAM_CFG_DRC, 0x00);
/* Prepare SDR */
SDRAM_WRITE_8(SDRAM_CFG_DRC, 0x01);
/* Action of writing MRS launches the initialisation sequence */
SDRAM_WRITE_8(SDRAM_CFG_DRC, 0x21);
/* Now enable the requests to the LMC */
SDRAM_WRITE_8(SDRAM_CFG_DRC, 0xA3);
/* Memory refresh */
SDRAM_WRITE_8(SDRAM_CFG_MCF, 0x34);
/* Wait for at least 2 refresh cycle (RefreshTime is in units of 32 SDRAM clock periods) */
for (ii=0 ; ii<1000 ; ii++);
for (Phase = 0 ; Phase < 4; Phase++)
{
switch(Phase) {
case 0:
SDRAM_WRITE_8(SDRAM_CFG_DRC, 0xA3);
break;
case 1:
SDRAM_WRITE_8(SDRAM_CFG_DRC, 0xA7);
break;
case 2:
SDRAM_WRITE_8(SDRAM_CFG_DRC, 0xAB);
break;
case 3:
SDRAM_WRITE_8(SDRAM_CFG_DRC, 0xAF);
break;
}
/* Write a word into SDRAM */
*sdram_pointer = 0x12345678;
/* Read the byte from SDRAM */
if (*sdram_pointer == 0x12345678)
{
/* Success: Phase was found ! */
break;
}
}
/* Sdram is running so lock the configuration registers */
SDRAM_WRITE_8(SDRAM_VID_LCK, 0x01);
}
void PrePokeLoopCallback(void) {
if (!PLLAlreadyInitialised())
{
ROM_ConfigurePLL();
ROM_ConfigureSDRAM();
}
}
void PostPokeLoopCallback(void) {
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -