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

📄 lowinit.c

📁 包括EPA协议栈
💻 C
字号:
#include "AT91RM9200.h"
#define LOWINIT_GLOBALS
#include "lowinit.h"
#undef LOWINIT_GLOBLAS

#define EBI_CS0_BASE_ADDRESS	     (0x10000000)
#define EBI_CS1_BASE_ADDRESS	     (0x20000000)
#define AT91C_SLOW_CLOCK           (32768)
//#define AT91C_PCK                (199065600)    // = 66355200 * 3
//#define AT91C_MCK                (66355200)     // = 115200 * 16 * 36 = 18432000 * 3.6
#define AT91C_PCK                  (160000000)    // = 80000000 * 2 = 18432000 / 72 * 625
#define AT91C_MCK                  (80000000)     // = 18432000 / 144 * 625
#define AT91C_DBG_BAND_RATE        (115200)

/*-------------------------------------------------------------------------------------------------*
 *- These macros definition determine clock output by pmc, including master clock (MCK), processor
 *- clock, programmable clock and USB port clock, which must be 48Mhz. 
 *- main clock -> pll A -> master clock controller -> master clock & processor clock
 *- main clock -> pll B -> programmable clock & USB port clock
 ;- PLLA output is set to 199.0656 MHz with setting below (160000000 = 18432000 / 72 * 625)
 ;- PLLB output is set to 48.054857 MHz with setting below (96000000 = 18432000 / 72 * 375)
 *-------------------------------------------------------------------------------------------------*/
#define CKGR_PLLRA_CFG             (0x270 << 16 | AT91C_CKGR_OUTA_2 | AT91C_CKGR_PLLACOUNT | 0x48)
#define CKGR_PLLRB_CFG             (0x01 << 28 | 0x176 << 16 | AT91C_CKGR_OUTB_0 | AT91C_CKGR_PLLBCOUNT | 0x48)
#define PMC_MCKR_CFG               (AT91C_PMC_CSS_PLLA_CLK | AT91C_PMC_PRES_CLK | AT91C_PMC_MDIV_2)
#define PMC_SYSCLK_CFG             (AT91C_PMC_PCK | AT91C_PMC_UDP | AT91C_PMC_MCKUDP)


void SpuriousHandler(void);

void SpuriousInt(void) {
	AT91F_DEBUG_Printk("\n\r-F- Spurious Interrupt detected\n\r");
	while (1);
}

void UndExcp(void) {
	AT91F_DEBUG_Printk("\n\r-F- Undefine Indicator Interrupt detected\n\r");
	while (1);
}
void SwiExcp(void) {
	AT91F_DEBUG_Printk("\n\r-F- Software Interrupt detected\n\r");
	while (1);
}

void PreAbtExcp(void) {
	AT91F_DEBUG_Printk("\n\r-F- Indicator Prefetch Abort Interrupt detected\n\r");
	while (1);
}

void DataAbtExcp(void) {
	AT91F_DEBUG_Printk("\n\r-F- Data Abort Interrupt detected\n\r");
	while (1);
}

void AT91F_LowLevel_Init(void) {

	PMCLowLevleInit(AT91C_BASE_PMC, AT91C_BASE_CKGR, AT91C_SLOW_CLOCK);

	AICLowLevelInit(AT91C_BASE_AIC, SpuriousHandler);

	SDRAMLowLevelInit();

	FlashLowLevelInit();

	DebugLowLevelInit();
	
	DebugPrint("\n\rAT91RM9200 LowLevelInit Complete!\n\r");
}

void AICLowLevelInit(AT91PS_AIC preg, PINTHDL phdl) {

	preg->AIC_IDCR = 0xFFFFFFFF;
	preg->AIC_ICCR = 0xFFFFFFFF;

	preg->AIC_EOICR = preg->AIC_EOICR;
	preg->AIC_EOICR = preg->AIC_EOICR;
	preg->AIC_EOICR = preg->AIC_EOICR;
	preg->AIC_EOICR = preg->AIC_EOICR;
	preg->AIC_EOICR = preg->AIC_EOICR;
	preg->AIC_EOICR = preg->AIC_EOICR;
	preg->AIC_EOICR = preg->AIC_EOICR;
	preg->AIC_EOICR = preg->AIC_EOICR;

	preg->AIC_SPU = (AT91_REG)phdl;
}

/*------------------------------------------------------------------------------------------------*
 *- Function: PMCLowLevleInit
 *- Parameter: preg, Start Address of PMC register group
 *- Return: void
 *- Brief: Low level init PMC, including main clock, pll clock, master clock, processor clock
 *------------------------------------------------------------------------------------------------*/
void PMCLowLevleInit(AT91PS_PMC pmcreg, AT91PS_CKGR pckgreg, unsigned int slk) {
	unsigned int mainclk;
	
	// Make sure system clocks is enabled
	pmcreg->PMC_SCER = PMC_SYSCLK_CFG;
	
	// Switch MCK source to slow clock if neccessory
	if(pmcreg->PMC_MCKR != 0) {
		pmcreg->PMC_MCKR = 0;
	}

	// Enable Main Oscillator if neccessory
	if(!(pckgreg->CKGR_MOR & AT91C_CKGR_MOSCEN)) {
		pckgreg->CKGR_MOR = AT91C_CKGR_MOSCEN | AT91C_CKGR_OSCOUNT;
		
		// Loop until Main Oscillator is stable
		while((pmcreg->PMC_SR & AT91C_PMC_MOSCS) && (pckgreg->CKGR_MCFR & AT91C_CKGR_MAINRDY));
		mainclk = ((pckgreg->CKGR_MCFR & 0xFFFF) * slk) >> 4;
	}

	// Configure PLLA and PLLB	
	pckgreg->CKGR_PLLAR = CKGR_PLLRA_CFG;
	pckgreg->CKGR_PLLBR = CKGR_PLLRB_CFG;
	while(!(pmcreg->PMC_SR & AT91C_PMC_LOCKA) && !(pmcreg->PMC_SR & AT91C_PMC_LOCKB));

	// Switch MCK back to PLLA clock
	pmcreg->PMC_MCKR = PMC_MCKR_CFG;
	while(!(pmcreg->PMC_SR & AT91C_PMC_MCKRDY));
}

/*------------------------------------------------------------------------------------------------*
 *- Function: FlashLowLevelInit
 *- Parameter: void
 *- Return: void
 *- Brief: Initialize flash
 *------------------------------------------------------------------------------------------------*/
void FlashLowLevelInit(void) {

	//* Setup MEMC to support CS0 == Flash
	AT91C_BASE_EBI->EBI_CSA &= (~AT91C_EBI_CS0A_BFC);
	AT91C_BASE_EBI->EBI_CFGR = (AT91C_EBI_DBPUC & 0x00) | (AT91C_EBI_EBSEN & 0x00);

	//* Setup Flash
	AT91C_BASE_SMC->SMC_CSR[0] = (FLASH_SMC_NWS | FLASH_SMC_WSEN | FLASH_SMC_TDF | FLASH_SMC_BAT | FLASH_SMC_DBW | FLASH_SMC_DRP | FLASH_SMC_ACCS | FLASH_SMC_RWSETUP | FLASH_SMC_RWHOLD);
}

/*------------------------------------------------------------------------------------------------*
 *- Function: SDRAMLowLevelInit
 *- Parameter: void
 *- Return: void
 *- Brief: Initialize SDRAM
 *------------------------------------------------------------------------------------------------*/
void SDRAMLowLevelInit(void) {
	unsigned int i;
	unsigned int* pSDRAM = (unsigned int *)EBI_CS1_BASE_ADDRESS;

	//* Configure PIOC as peripheral (D16/D31)
	AT91F_PIO_CfgPeriph(AT91C_BASE_PIOC, AT91C_PIOC_D16_D31, 0);
	
	//* 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;
	*pSDRAM = 0;
}

/*------------------------------------------------------------------------------------------------*
 *- Function: DebugLowLevelInit
 *- Parameter: void
 *- Return: void
 *- Brief: Enable main debug port
 *------------------------------------------------------------------------------------------------*/
void DebugLowLevelInit(void) {

	AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, AT91C_PA31_DTXD | AT91C_PA30_DRXD, 0);
	AT91F_US_Configure((AT91PS_USART)AT91C_BASE_DBGU, 80000000,	AT91C_US_ASYNC_MODE, 115200, 0);
	AT91C_BASE_DBGU->US_CR = AT91C_US_RSTRX | AT91C_US_TXEN | AT91C_US_RXEN;
}

/*------------------------------------------------------------------------------------------------*
 *- Function: DebugPrintk
 *- Parameter: buffer, points at charator buffer
 *- Return: void
 *- Brief: Send charactors through debug USART port
 *------------------------------------------------------------------------------------------------*/
void DebugPrint(char *buffer) {
	while(*buffer != '\0') {
		while(!AT91F_US_TxReady((AT91PS_USART)AT91C_BASE_DBGU)); 
			AT91F_US_PutChar((AT91PS_USART)AT91C_BASE_DBGU, *buffer++);
	}
}

⌨️ 快捷键说明

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