书接上回,看看UBL对平台的初始化,主要是调用了DEVICE_init函数,函数内容如下:
Uint32 DEVICE_init() { Uint32 status = E_PASS; // Mask all interrupts AINTC->INTCTL = 0x4; AINTC->EABASE = 0x0; AINTC->EINT0 = 0x0; AINTC->EINT1 = 0x0; // Clear all interrupts AINTC->FIQ0 = 0xFFFFFFFF; AINTC->FIQ1 = 0xFFFFFFFF; AINTC->IRQ0 = 0xFFFFFFFF; AINTC->IRQ1 = 0xFFFFFFFF; #ifndef SKIP_LOW_LEVEL_INIT POR_RESET(); // System PSC setup - enable all DEVICE_PSCInit(); DEVICE_pinmuxControl(0,0xFFFFFFFF,0x00FD0000); // All Video Inputs
DEVICE_pinmuxControl(1,0xFFFFFFFF,0x00145555); // All Video Outputs
DEVICE_pinmuxControl(2,0xFFFFFFFF,0x000000DA); // EMIFA
DEVICE_pinmuxControl(3,0xFFFFFFFF,0x00180000); // SPI0, SPI1, UART1, I2C, SD0, SD1, McBSP0, CLKOUTs
DEVICE_pinmuxControl(4,0xFFFFFFFF,0x55555555); // MMC/SD0 instead of MS, SPI0
GPIO->DIR02 &= 0xfeffffff; GPIO->CLRDATA02 = 0x01000000; // System PLL setup if (status == E_PASS) status |= DEVICE_PLL1Init(PLL1_Mult); // DDR PLL setup if (status == E_PASS) status |= DEVICE_PLL2Init(); // DDR2 module setup if (status == E_PASS) status |= DEVICE_DDR2Init(); #endif // AEMIF Setup if (status == E_PASS) status |= DEVICE_EMIFInit(); // UART0 Setup if (status == E_PASS) status |= DEVICE_UART0Init(); // TIMER0 Setup if (status == E_PASS) status |= DEVICE_TIMER0Init(); // I2C0 Setup if (status == E_PASS) status |= DEVICE_I2C0Init(); return status; }
|
首先屏蔽和清除中断,然后调用DEVICE_PSCInit函数实现对各模块的电源时钟使能,实质是调用PSC电源时钟管理模块的寄存器实现,函数内容如下:
void DEVICE_PSCInit() { unsigned char i=0; unsigned char lpsc_start; unsigned char lpsc_end,lpscgroup,lpscmin,lpscmax; unsigned int PdNum = 0; lpscmin =0; lpscmax =2; for(lpscgroup=lpscmin ; lpscgroup <=lpscmax; lpscgroup++) { if(lpscgroup==0) { lpsc_start = 0; // Enabling LPSC 3 to 28 SCR first
lpsc_end = 28; } else if (lpscgroup == 1) { /* Skip locked LPSCs [29-37] */ lpsc_start = 38; lpsc_end = 47; } else { lpsc_start = 50; lpsc_end = 51; } //NEXT=0x3, Enable LPSC's for(i=lpsc_start; i<=lpsc_end; i++) { PSC->MDCTL[i] |= 0x3; } //Program goctl to start transition sequence for LPSCs PSC->PTCMD = (1<<PdNum); //Wait for GOSTAT = NO TRANSITION from PSC for Pdomain 0 while(! (((PSC->PTSTAT >> PdNum) & 0x00000001) == 0)); //Wait for MODSTAT = ENABLE from LPSC's for(i=lpsc_start; i<=lpsc_end; i++) { while(!((PSC->MDSTAT[i] & 0x0000001F) == 0x3)); } } }
|
然后调用DEVICE_pinmuxControl函数决定复用引脚的功能选择,详见数据手册查看引脚功能。
接着调用DEVICE_PLL1Init函数实现了PLL1的配置,预分频,倍频,后分频,分频到各个模块,其设置顺序可以参看用户指南ARM子系统文档,有详细的介绍,PLL2类似不再赘述,函数内容如下:
Uint32 DEVICE_PLL1Init(Uint32 PLLMult) { unsigned int CLKSRC=0x0; unsigned int j; /*Power up the PLL*/ PLL1->PLLCTL &= 0xFFFFFFFD; PLL1->PLLCTL &= 0xFFFFFEFF; PLL1->PLLCTL |= CLKSRC<<8; /*Set PLLENSRC '0', PLL Enable(PLLEN) selection is controlled through MMR*/ PLL1->PLLCTL &= 0xFFFFFFDF; /*Set PLLEN=0 => PLL BYPASS MODE*/ PLL1->PLLCTL &= 0xFFFFFFFE; UTIL_waitLoop(150); // PLLRST=1(reset assert) PLL1->PLLCTL |= 0x00000008; UTIL_waitLoop(300); /*Bring PLL out of Reset*/ PLL1->PLLCTL &= 0xFFFFFFF7; //Program the Multiper and Pre-Divider for PLL1 PLL1->PLLM = 0x51; // VCO will 24*2M/N+1 = 486Mhz
PLL1->PREDIV = 0x8000|0x7; PLL1->SECCTL = 0x00470000; // Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1 PLL1->SECCTL = 0x00460000; // Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0 PLL1->SECCTL = 0x00400000; // Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0 PLL1->SECCTL = 0x00410000; // Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1 //Program the PostDiv for PLL1 PLL1->POSTDIV = 0x8000; // Post divider setting for PLL1 PLL1->PLLDIV2 = 0x8001; PLL1->PLLDIV3 = 0x8001; // POST DIV 486/2 -> MJCP/HDVICP PLL1->PLLDIV4 = 0x8003; // POST DIV 486/4 -> EDMA/EDMA CFG PLL1->PLLDIV5 = 0x8001; // POST DIV 486/2 -> VPSS PLL1->PLLDIV6 = 0x8011; // 27Mhz POST DIV 486/18 -> VENC PLL1->PLLDIV7 = 0x8000; // POST DIV 486/2 -> DDR PLL1->PLLDIV8 = 0x8003; // POST DIV 486/4 -> MMC0/SD0 PLL1->PLLDIV9 = 0x8001; // POST DIV 486/2 -> CLKOUT
UTIL_waitLoop(300); /*Set the GOSET bit */ PLL1->PLLCMD = 0x00000001; // Go
UTIL_waitLoop(300); /*Wait for PLL to LOCK */ while(! (((SYSTEM->PLL0_CONFIG) & 0x07000000) == 0x07000000)); /*Enable the PLL Bit of PLLCTL*/ PLL1->PLLCTL |= 0x00000001; // PLLEN=0 return E_PASS; }
|
阅读(2437) | 评论(1) | 转发(0) |