📄 main.c
字号:
#include "AT91RM9200.h"
#include "lib_AT91RM9200.h"
#include "def.h"
#include "config.h"
#include "slib.h"
#include "console.h"
#include "twi.h"
#include "params.h"
///--------------------------------------------------------------------------------------
#define VPint *(volatile unsigned int *)
U8 int2ch(U8 data);
U8 ch2int(U8 data);
void commDebug(void);
///--------------------------------------------------------------------------------------
// The following DBGU ASM handler is defined in asm_isr.s
//extern void AT91F_ASM_DBGU_Handler(void);
U32 downloadAddress, downloadFileSize;
//char hex_ch[16] = {'0','1','2','3','4','5','6','7',
// '8','9','a','b','c','d','e','f'};
static U8 OurEmacAddr[6] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
volatile U32 StTick;
void (*StIrqHandler)(void);
void (*DbguIrqHandler)(void);
static void SysIrqHandler(void)
{
/* ========== Systimer interrupt ============== */
if(AT91F_ST_GetInterruptMaskStatus(AT91C_BASE_ST) & AT91C_ST_PITS) {
if (AT91C_BASE_ST->ST_SR & AT91C_ST_PITS) {
StTick++;
if(*StIrqHandler)
(*StIrqHandler)();
return;
}
}
if(*DbguIrqHandler)
(*DbguIrqHandler)();
}
//统一的中断入口处理
void __irq irq_handler(void)
{
void (*svr)(void);
AT91PS_AIC ptr = AT91C_BASE_AIC;
U32 i;
// U8 irq_idx;
//取得中断入口地址可用AIC_IVR或用AIC_ISR作索引得到AIC_SVR数组中的地址
i = ptr->AIC_IVR; //read AIC_IVR
// irq_idx = ptr->AIC_ISR&0x1f;
//边沿触发中断必须以此清中断
// AT91F_AIC_ClearIt(AT91C_BASE_AIC, irq_idx);
// Write in the IVR to support Protect Mode
// No effect in Normal Mode
// De-assert the NIRQ and clear the source in Protect Mode
ptr->AIC_IVR = (AT91_REG)ptr;
// putch('I');
// printf("%x,%x,%x\n", irq_idx, ptr->AIC_IPR, ptr->AIC_CISR);
svr = (void (*)(void))i;//ptr->AIC_SVR[irq_idx];
(*svr)();
AT91F_AIC_AcknowledgeIt(ptr); //退出中断前必须应答
}
static void InitPio(void)
{
//led
AT91F_PIO_CfgOutput(AT91C_BASE_PIOC, AT91C_PIO_PC0|AT91C_PIO_PC2|AT91C_PIO_PC4|AT91C_PIO_PC5);
AT91F_PIO_ClearOutput(AT91C_BASE_PIOC, AT91C_PIO_PC0|AT91C_PIO_PC2|AT91C_PIO_PC4|AT91C_PIO_PC5);
//key
//AT91F_PIO_CfgInput(AT91C_BASE_PIOB, AT91C_PIO_PB6|AT91C_PIO_PB7|AT91C_PIO_PB8|AT91C_PIO_PB9);
AT91F_PIO_CfgInput(AT91C_BASE_PIOA, AT91C_PIO_PA24);
AT91F_PIO_CfgInput(AT91C_BASE_PIOB, AT91C_PIO_PB1|AT91C_PIO_PB2|AT91C_PIO_PB6);
//AT91F_PIO_CfgOutput(AT91C_BASE_PIOB, AT91C_PIO_PB1|AT91C_PIO_PB2|AT91C_PIO_PB6);
///AT91F_PIO_ClearOutput(AT91C_BASE_PIOB, AT91C_PIO_PB1|AT91C_PIO_PB2|AT91C_PIO_PB6);
AT91F_PIO_CfgOutput(AT91C_BASE_PIOB, AT91C_PIO_PB7);
AT91F_PIO_ClearOutput(AT91C_BASE_PIOB, AT91C_PIO_PB7);
AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, ((U32) 1 << AT91C_ID_PIOB));
AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, ((U32) 1 <<AT91C_ID_PIOA ));
//buzzer
/*
AT91F_PIO_CfgPeriph(
AT91C_BASE_PIOB, // PIO controller base address
((unsigned int) AT91C_PB27_PCK0 ), // Peripheral A
0); // Peripheral B
*/
/*AT91F_PMC_EnablePCK(AT91C_BASE_PMC,
0, //PCK0
AT91C_PMC_CSS_SLOW_CLK, //32768
AT91C_PMC_PRES_CLK_16); //1/16
*/
//delay(200);
//AT91F_PIO_CfgInput(AT91C_BASE_PIOB, AT91C_PIO_PB27);
//delay(200);
}
U32 GetFlashID(void);
int SectorProg(U32 begin, U16 *data, U32 size);
int SectorRead(U32 begin, U16 *data, U32 size);
void start_kernel(U32, U32);
static void InitNorFlash(void)
{
#ifdef NOR_SUPPORT
// Setup MEMC to support CS0 = static memory
AT91C_BASE_EBI->EBI_CSA &= ~1;
// [D15:0] pull-up
AT91C_BASE_EBI->EBI_CFGR = (AT91C_EBI_DBPUC & 0x00) | (AT91C_EBI_EBSEN & 0x00);
// Setup Flash 存储器参数设置CS0-CS7对应SMC2_CSR[0]-SMC2_CSR[7]
AT91C_BASE_SMC2->SMC2_CSR[0] = (AT91C_SMC2_NWS & 0x7f) | AT91C_SMC2_WSEN |
(AT91C_SMC2_TDF & 0x200)| AT91C_SMC2_BAT |
AT91C_SMC2_DBW_16 | AT91C_SMC2_ACSS_STANDARD;/* |
AT91C_SMC2_RWSETUP | AT91C_SMC2_RWHOLD; */
printf("FLASH ID = %x\n", GetFlashID());
#endif
}
static void RunProgFrNor(U32 addr, U32 size)
{
#ifdef NOR_SUPPORT
downloadAddress = 0x20800000;
downloadFileSize = 0x200000;
printf("Boot From Nor Flash 0x%8x, Size 0x%x\n",
downloadAddress, downloadFileSize);
SectorRead(0x100000, (U16 *)downloadAddress, downloadFileSize);
start_kernel(downloadAddress, 0);
#endif
}
static void WrFileToNor(U32 addr, U32 size)
{
#ifdef NOR_SUPPORT
printf("Write Data From 0x%8x, Size 0x%x to Nor Flash\n", addr, size);
SectorProg(0x100000, (U16 *)addr, size);
#endif
}
void GetNandFlashChip(void);
static void InitNandFlash(void)
{
#ifdef NAND_SUPPORT
AT91F_PIO_CfgPeriph(
AT91C_BASE_PIOC, // PIO controller base address
(unsigned int) AT91C_PC1_BFRDY_SMOE | (unsigned int) AT91C_PC3_BFBAA_SMWE, // Peripheral A
0); // Peripheral B
// Setup MEMC to support CS3 = NAND Flash
AT91C_BASE_EBI->EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia;
// [D15:0] pull-up
AT91C_BASE_EBI->EBI_CFGR = (AT91C_EBI_DBPUC & 0x00) | (AT91C_EBI_EBSEN & 0x00);
// Setup Flash 存储器参数设置CS0-CS7对应SMC2_CSR[0]-SMC2_CSR[7]
AT91C_BASE_SMC2->SMC2_CSR[3] = (AT91C_SMC2_NWS & 0x4) | AT91C_SMC2_WSEN |
(AT91C_SMC2_TDF & 0x200)| AT91C_SMC2_BAT |
AT91C_SMC2_DBW_8;
// Enable PIOC clock for input
AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, ((unsigned int) 1 << AT91C_ID_PIOC));
AT91F_PIO_CfgInput (AT91C_BASE_PIOC, AT91C_PIO_PC14);
AT91F_PIO_CfgPullup(AT91C_BASE_PIOC, AT91C_PIO_PC14);
AT91F_PIO_CfgOutput (AT91C_BASE_PIOC, AT91C_PIO_PC15);
// AT91F_PIO_GetInput(AT91C_BASE_PIOC) & AT91C_PIO_PC14;
GetNandFlashChip();
#endif
}
#ifdef IIC_SUPPORT
#define EEP_RW_CHK_CNT 32
#endif /* IIC_SUPPORT */
static void InitTwi(void)
{
#ifdef IIC_SUPPORT
int loop;
char data[EEP_RW_CHK_CNT];
// Configure TWI PIOs
AT91F_TWI_CfgPIO ();
AT91F_PIO_CfgOpendrain(AT91C_BASE_PIOA, (unsigned int) AT91C_PA25_TWD);
// Configure PMC by enabling TWI clock
AT91F_TWI_CfgPMC ();
// Configure TWI in master mode
AT91F_TWI_Configure (AT91C_BASE_TWI);
// Set TWI Clock Waveform Generator Register
AT91F_SetTwiClock(AT91C_BASE_TWI);
// IIC启动,先测试IIC读
printf("EEPREOM address is 0x%x\n", AT91C_EEPROM_I2C_ADDRESS);
// for(loop=0; loop<EEP_RW_CHK_CNT; loop++)
// data[loop] = loop;
// Write and read iic
// AT91F_TWI_Write(AT91C_BASE_TWI, 0x0, data, EEP_RW_CHK_CNT);
// Wait 10 ms before data is written into EEPROM
// puts("Wait at least 10 ms before value is written into EEPROM\n");
// for (loop=0; loop<100000; loop++);
for(loop=0; loop<EEP_RW_CHK_CNT; loop++)
data[loop] = 0;
AT91F_TWI_Read(AT91C_BASE_TWI, 0x0, data, EEP_RW_CHK_CNT);
for(loop=0; loop<EEP_RW_CHK_CNT; loop++)
if(data[loop]!=loop)
break;
printf("Check data %s\n", (loop==EEP_RW_CHK_CNT)?"success":"fail");
#endif /* IIC_SUPPORT */
}
static void ShowLed(U32 led)
{
U8 set = 0, clr = 0;
if(led&1)
set |= 1;
else
clr |= 1;
if(led&2)
set |= 4;
else
clr |= 4;
if(led&4)
set |= 0x10;
else
clr |= 0x10;
if(led&8)
set |= 0x20;
else
clr |= 0x20;
AT91F_PIO_SetOutput (AT91C_BASE_PIOC, set);
AT91F_PIO_ClearOutput (AT91C_BASE_PIOC, clr);
}
U16 GetKeyStatus(void)
{
U16 r=0;
U32 k=0;
k = AT91F_PIO_GetInput(AT91C_BASE_PIOB);
//printf("PB = %d\n",k);
if(!(k&(1<<1)))
{
r |= 2;
// printf("r1=%x\n",r);
}
if(!(k&(1<<2)))
{
r |= 3;
// printf("r2=%x\n",r);
}
if(!(k&(1<<6)))
{
r |= 4;
// printf("r3=%x\n",r);
}
if(!(AT91F_PIO_GetInput(AT91C_BASE_PIOA)&(1<<24)))
{
r |= 1;
// printf("r3=%x\n",r);
}
//printf("r4=%d\n",r);
return r;
//return (AT91F_PIO_GetInput(AT91C_BASE_PIOB));
}
void ComDownload(U32 a1, U32 a2);
void Program_eep(U32 addr, U32 size);
void WrFileToNF(U32 FileAddr, U32 FileSize);
void RdFileFrNF(U32 FileAddr, U32 FileSize);
void EraseNandPart(U32 a1, U32 a2);
void RunProgFrNor(U32 addr, U32 size);
//void tftp_main(U32 addr, U32 dummy);
void FindNandBoot(void);
static struct {
void (*FuncAddr)(U32, U32);
char *str;
} Functions[] = {
{ComDownload, "Download File By Uart(DNW)"},
//{tftp_main, "Download File By Tftp"},
//{XmodemDownload, "Download File By Xmodem"},
{Program_eep, "Write File To IIC Rom"},
{WrFileToNF, "Write File To Nand Flash"},
{RdFileFrNF, "Run Pragram From Nand Flash"},
{EraseNandPart, "Erase Nand Flash Partition"},
{WrFileToNor, "Write File To Nor Flash"},
{RunProgFrNor, "Run Program From Nor Flash"},
// {TestNandFlash, "Test nand flash"},
{0, 0}
};
//*----------------------------------------------------------------------------
//* \fn main
//* \brief
//*
//*----------------------------------------------------------------------------
int main(void)
{
U16 i;
U8 c;
int timeout=3000;
int bootflag=1;
AT91PS_EMAC pEmac = AT91C_BASE_EMAC;
AT91F_RTC_InterruptDisable( AT91C_BASE_RTC , 0x1f );
AT91F_ST_DisableIt( AT91C_BASE_ST , 0xf );
AT91C_BASE_ST->ST_PIMR = 328; // 328/32768 S
// *AT91C_PMC_IDR = 0xf0f; //disabled in InitSDRAM(init.c)
// printf("\nST_PIMR = 0x%08x\n", AT91C_BASE_ST->ST_PIMR);
// AT91F_ST_EnableIt(AT91C_BASE_ST, AT91C_ST_PITS);
//设置网口MAC地址,先使能EMAC时钟,启动linux前要设置好MAC地址.
AT91F_EMAC_CfgPMC();
pEmac->EMAC_SA1L = ( ( int ) OurEmacAddr[2] << 24 ) |
( ( int ) OurEmacAddr[3] << 16 ) |
( ( int ) OurEmacAddr[4] << 8 ) |
OurEmacAddr[5];
pEmac->EMAC_SA1H = ( ( int ) OurEmacAddr[0] << 8 ) | OurEmacAddr[1];
//when set an irq handler, the irq will be disabled in AT91F_AIC_ConfigureIt,
//so enable it after AT91F_AIC_ConfigureIt!!!
AT91F_AIC_ConfigureIt( AT91C_BASE_AIC , // AIC base address
AT91C_ID_SYS , // System peripheral ID
AT91C_AIC_PRIOR_HIGHEST , // Max priority
AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE , // Level sensitive
SysIrqHandler ); // 将设置处理函数地址填入AIC_SVC[AT91C_ID_SYS]
//使能系统中断(包括ST,DBGU等)
AT91F_AIC_EnableIt( AT91C_BASE_AIC , AT91C_ID_SYS );
downloadAddress = LINUX_KERNEL_ADDR;
/* while(1) { //读NAND FLASH 的BUSY脚状态
if(AT91F_PIO_GetInput(AT91C_BASE_PIOC)&AT91C_PIO_PC14)
putch('1');
else
putch('0');
delay(100);
}*/
/* while(1) {
delay(300);
putch('a');
}*/
//puts("\n test for at91rm9200\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -