init.c
来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 404 行 · 第 1/2 页
C
404 行
//*----------------------------------------------------------------------------
//* 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
//* Object : Low level initialisations written in C
//* Creation : FB 23/10/2002
//* Modify : SBb 10/06/2005
//*
//*----------------------------------------------------------------------------
#include "init.h"
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
//*----------------------------------------------------------------------------
//* \fn AT91F_IRQ_HANDLER
//* \brief This function performs very low level HW initialization
//*----------------------------------------------------------------------------
__irq __arm void AT91F_IRQ_HANDLER(void)
{
VoidFpnt_t Fpnt = (VoidFpnt_t)AT91C_BASE_AIC->AIC_IVR;
AT91C_BASE_AIC->AIC_IVR = 0; // Debug mode
Fpnt();
AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);
}
//*----------------------------------------------------------------------------
//* \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)
/////////////////////////////////////////////////////////////////////////////////////////////////////
//* 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);
// Eanble main clock OSC and wait until expire the delay counter
AT91C_BASE_CKGR->CKGR_MOR = 0x0000FF01; // PMC_MOR: MOSCEN = 1, enable main clock
while((AT91C_BASE_CKGR->CKGR_MCFR & AT91C_CKGR_MAINRDY) == 0); // wair time out
//* Check if Input & Output Frequencies are in the correct range
MainClock = AT91F_CKGR_GetMainClock(AT91C_BASE_CKGR,SLOWCLOCK);
if((MainClock < (MAIN_OSC_CLK * 0.9)) || (MainClock > (MAIN_OSC_CLK * 1.1)))
return FALSE;
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 = AT91C_PMC_CSS_MAIN_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_Register;
AT91C_BASE_PMC->PMC_MCKR = MCKR_Register;
//* 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;
volatile 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_9 | AT91C_SDRC_NR_12 | AT91C_SDRC_NB_4_BANKS | AT91C_SDRC_CAS_2
| 0x100 | 0x4000 | 0x8000
| 0x880000
| 0x21000000;
//* 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;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?