⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init_c.c

📁 FLASH烧写程序
💻 C
字号:
//*----------------------------------------------------------------------------
//*         ATMEL Microcontroller Software Support  -  ROUSSET  -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name           : init_c.c
//* Object              : Low level initialisations written in C
//* Creation            : FB   23/10/2002
//*
//*----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
#include "AT91RM9200.h"
#include "lib_AT91RM9200.h"

#define	FALSE					0
#define	TRUE					1
#define	DELAY_PLL				200
#define DELAY_MAIN_FREQ			200

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Configuration for a Quartz 18.432000 MHz
/////////////////////////////////////////////////////////////////////////////////////////////////////

#define	PLLAR 					0x2026BE04	//* 179,712000 MHz 
#define	PLLBR 					0x10483E0E	//* 48,054857 MHz (divider by 2 for USB)
#define	MCKR  					0x00000202	//* PCK/3 = MCK Master Clock = 59,904000MHz with PLLA selected 0x00000202
#define SLOWCLOCK				32768		//* In Hz

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Frequencies Range
/////////////////////////////////////////////////////////////////////////////////////////////////////

#define INPUT_FREQ_MIN			900000
#define INPUT_FREQ_MAX			32000000


#define BASE_EBI_CS0_ADDRESS	0x10000000	//* base address to access memory on CS0
#define BASE_EBI_CS1_ADDRESS	0x20000000	//* base address to access memory on CS1

#define OUTPUT_FREQ_MIN			50000000
#define OUTPUT_FREQ_MAX			240000000






/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////

//*----------------------------------------------------------------------------
//* \fn    AT91F_WaitForMainClockFrequency
//* \brief This function performs very low level HW initialization
//*----------------------------------------------------------------------------
unsigned char AT91F_WaitForMainClockFrequency()
{
	 volatile char	tmp	= 0;

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Step 2.
// Checking the Main Oscillator Frequency (Optional)
/////////////////////////////////////////////////////////////////////////////////////////////////////
    AT91C_BASE_CKGR->CKGR_MOR=0x1;
	//* Determine the main clock frequency
	
	while(!(AT91C_BASE_CKGR->CKGR_MCFR & AT91C_CKGR_MAINRDY) && (tmp++ < DELAY_MAIN_FREQ));

	if (tmp >= DELAY_MAIN_FREQ)
		return FALSE;

	return TRUE;
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_CheckPLL_FrequencyRange
//* \brief This function performs very low level HW initialiszation
//*----------------------------------------------------------------------------
unsigned char AT91F_CheckPLL_FrequencyRange(int MainClock,int pllDivider ,int pllMultiplier)
{
	if(pllDivider == 0)
		return FALSE;

	//* Check Input Frequency
	if( ((MainClock/pllDivider) < INPUT_FREQ_MIN)
	 || ((MainClock/pllDivider) > INPUT_FREQ_MAX) )
		return FALSE;

	//* Check Output Frequency
	if( ((MainClock/pllDivider*pllMultiplier) < OUTPUT_FREQ_MIN)
	 || ((MainClock/pllDivider*pllMultiplier) > OUTPUT_FREQ_MAX) )
		return FALSE;

	return TRUE;
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_InitClocks
//* \brief This function performs very low level HW initialization
//*----------------------------------------------------------------------------
	unsigned char AT91F_InitClocks(int PLLAR_Register,int PLLBR_Register ,int MCKR_Register)
{
	volatile char 	tmp = 0;
	unsigned int	MainClock;
	unsigned int 	pllDivider,pllMultiplier;
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Optionnal
/////////////////////////////////////////////////////////////////////////////////////////////////////

	//* Check if Input & Output Frequencies are in the correct range

	MainClock 		= AT91F_CKGR_GetMainClock(AT91C_BASE_CKGR,SLOWCLOCK);

	pllDivider    	= (PLLAR_Register  & AT91C_CKGR_DIVA);
	pllMultiplier 	= ((PLLAR_Register  & AT91C_CKGR_MULA) >> 16) + 1;
	if(AT91F_CheckPLL_FrequencyRange(MainClock, pllDivider , pllMultiplier) == FALSE)
		return FALSE;

	pllDivider    	= (PLLBR_Register  & AT91C_CKGR_DIVB);
	pllMultiplier 	= ((PLLBR_Register  & AT91C_CKGR_MULB) >> 16) + 1;
	if(AT91F_CheckPLL_FrequencyRange(MainClock, pllDivider , pllMultiplier) == FALSE)
		return FALSE;

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Step 3.
// Setting PLLA and Divider A
/////////////////////////////////////////////////////////////////////////////////////////////////////

	AT91C_BASE_CKGR->CKGR_PLLAR = PLLAR_Register;
	//* Wait for PLLA stabilization LOCKA bit in PMC_SR
	tmp = 0;
	while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA) && (tmp++ < DELAY_PLL) ) ;

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Step 4.
// Setting PLLB and Divider B
/////////////////////////////////////////////////////////////////////////////////////////////////////

	AT91C_BASE_CKGR->CKGR_PLLBR = PLLBR_Register;
	//* Wait for PLLB stabilization LOCKB bit in PMC_SR
	tmp = 0;
	while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKB) && (tmp++ < DELAY_PLL) ) ;

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Step 5.
// Selection of Master Clock MCK (and Processor Clock PCK)
/////////////////////////////////////////////////////////////////////////////////////////////////////

	//* Constraints of the Master Clock selection sequence
	//* Write in the MCKR dirty value concerning the clock selection CSS then overwrite it in a second sequence
	
	AT91C_BASE_PMC->PMC_MCKR =0x1;//AT91C_PMC_CSS_SLOW_CLK;
	//* Wait until the master clock is established
	tmp = 0;
	while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) && (tmp++ < DELAY_MAIN_FREQ) );

	//* Second sequence
	AT91C_BASE_PMC->PMC_MCKR =MCKR;
	//* Wait until the master clock is established
	tmp = 0;
	while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) && (tmp++ < DELAY_MAIN_FREQ) );

	return TRUE;
}
//*----------------------------------------------------------------------------
//* \fn    AT91F_InitSDRAM
//* \brief This function performs very low level HW initialisation
//*----------------------------------------------------------------------------
void AT91F_InitSDRAM()
{
	int 	i;
	int 	*pSDRAM = (int *)BASE_EBI_CS1_ADDRESS;

	//* Configure PIOC as peripheral (D16/D31)
	AT91F_SDRC_CfgPIO();
	
	//* Setup MEMC to support CS1=SDRAM
	AT91C_BASE_EBI->EBI_CSA |= AT91C_EBI_CS1A;
	AT91C_BASE_EBI->EBI_CFGR = (AT91C_EBI_DBPUC & 0x00) | (AT91C_EBI_EBSEN & 0x00);

	//* Init SDRAM

	//* 1. A minimum pause of 200us is provided to precede any signal toggle
	AT91C_BASE_SDRC->SDRC_CR = AT91C_SDRC_NC_8 | AT91C_SDRC_NR_12 | AT91C_SDRC_NB_4_BANKS | AT91C_SDRC_CAS_2
								| 0x100 | 0x4000 | 0x8000
								| 0x880000
								| 0x2A000000;
								
   /* AT91C_BASE_SDRC->SDRC_CR = AT91C_SDRC_NC_8 | AT91C_SDRC_NR_12 | AT91C_SDRC_NB_4_BANKS | AT91C_SDRC_CAS_2
								| 0x100 | 0x3800|0x10000|0x900000|0x2A000000;
								*/
    AT91C_BASE_SDRC->SDRC_MR =AT91C_SDRC_DBW_32_BITS;
    
  	//* 2. A Precharge All command is issued to the SDRAM
	AT91C_BASE_SDRC->SDRC_MR = AT91C_SDRC_MODE_PRCGALL_CMD;
	*pSDRAM = 0;

	//* 3. Eight Auto-refresh are provided
	AT91C_BASE_SDRC->SDRC_MR = AT91C_SDRC_MODE_RFSH_CMD;
	for(i=0;i<8;i++)
		*pSDRAM = 0;

	//* 4. A mode register cycle is issued to program the SDRAM parameters
	AT91C_BASE_SDRC->SDRC_MR = AT91C_SDRC_MODE_LMR_CMD;
	*(pSDRAM+0x80) = 0;

	//* 5. Write refresh rate into SDRAMC refresh timer COUNT register
	AT91C_BASE_SDRC->SDRC_TR = (AT91C_SDRC_COUNT & 0x2E0);
	*pSDRAM = 0;

	//* 6. A Normal Mode Command is provided, 3 clocks after tMRD is set
	AT91C_BASE_SDRC->SDRC_MR = AT91C_SDRC_MODE_NORMAL_CMD;
	*pSDRAM = 0;

}


//*----------------------------------------------------------------------------
//* \fn    AT91F_LowLevelInit
//* \brief This function performs very low level HW initialization
//*----------------------------------------------------------------------------
extern void AT91F_LowLevelInit()
{
	unsigned char 	status;
  
	AT91F_EnableICache();
	
    status = AT91F_WaitForMainClockFrequency();
    
    status = AT91F_InitClocks(PLLAR,PLLBR,MCKR);
    
    AT91F_InitSDRAM();
    

}
   
	
	


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -