/*---------------------------------------------------------------------------- */
/* 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 */
/* */
/*----------------------------------------------------------------------------*/
#include "AT91RM9200.h"
/* //////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////// */
#define FALSE 0
#define TRUE 1
#define DELAY_PLL 100
#define DELAY_MAIN_FREQ 100
#define INPUT_FREQ_MIN 900000
#define INPUT_FREQ_MAX 32000000
#define MASTER_CLOCK 59904000
// #define MASTER_CLOCK 45000000
#define QUARTZ_18432 1
#if QUARTZ_18432
#define PLLAR 0x20263E04 /* 180 MHz for PLLA */
#define PLLBR 0x10483E0E /* 48,054857 MHz (divider by 2 for USB) */
#else /* 4.608MHZ */
#define PLLAR 0x20263E01 /* 179,712000 MHz for PCK for 4.608 */
#define PLLBR 0x10673E05 /* 48,054857 MHz (divider by 2 for USB) */
#endif
#define MCKR 0x0000202 /* PLLA=180 , == CPU = 180MHZ, MASTER_CLOCK = 60MHZ */
//#define MCKR 0x0000302 /* PLLA=180 , == CPU = 180MHZ, MASTER_CLOCK = 45MHZ */
#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 80000000
#define OUTPUT_FREQ_MAX 240000000
#define C1_IDC (1<<2) /* icache and/or dcache off/on */
/* //////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////*/
#define AT91C_BASE_SDRAM 0x20000000
#define AT91C_MASTER_CLOCK 48000000
#define AT91C_BAUD_RATE 115200
void AT91F_PIO_CfgPeriph(
AT91PS_PIO pPio, // \arg pointer to a PIO controller
unsigned int periphAEnable, // \arg PERIPH A to enable
unsigned int periphBEnable) // \arg PERIPH B to enable
{
pPio->PIO_ASR = periphAEnable;
pPio->PIO_BSR = periphBEnable;
pPio->PIO_PDR = (periphAEnable | periphBEnable); // Set in Periph mode
}
/*--------------------------------------------------------------------------------------*/
/* Function Name : AT91F_InitSDRAM */
/* Object : Initialize the SDRAM */
/*--------------------------------------------------------------------------------------*/
void AT91F_InitSDRAM()
{
volatile int *pSDRAM = (int *)AT91C_BASE_SDRAM;
/* Configure PIOC as peripheral (D16/D31) */
AT91F_PIO_CfgPeriph( AT91C_BASE_PIOC, 0xFFFF0000, 0);
/*Setup MEMC to support all connected memories (CS0 = FLASH; CS1=SDRAM)*/
AT91C_BASE_EBI->EBI_CSA = AT91C_EBI_CS1A;
/*Init SDRAM*/
AT91C_BASE_SDRC->SDRC_CR = 0x2188c159;
AT91C_BASE_SDRC->SDRC_MR = 0x02;
*pSDRAM = 0;
AT91C_BASE_SDRC->SDRC_MR = 0x04;
*pSDRAM = 0;
*pSDRAM = 0;
*pSDRAM = 0;
*pSDRAM = 0;
*pSDRAM = 0;
*pSDRAM = 0;
*pSDRAM = 0;
*pSDRAM = 0;
AT91C_BASE_SDRC->SDRC_MR = 0x03;
*(pSDRAM + 0x80) = 0;
AT91C_BASE_SDRC->SDRC_TR= 0x2e0;
*pSDRAM = 0;
AT91C_BASE_SDRC->SDRC_MR = 0;
*pSDRAM = 0;
}
/*---------------------------------------------------------------------------- */
/* \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(unsigned int MainClock,unsigned int pllDivider , unsigned 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 */
/* Get Main Clock */
MainClock = (((AT91C_BASE_CKGR->CKGR_MCFR) & AT91C_CKGR_MAINF) * 32768) >> 4;
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 Mas