继续在DEVICE_init函数中,下面是调用DEVICE_DDR2Init函数来配置DDR控制器,这是UBL中重要的一部分,如果硬件电路需要更换内存芯片的话,需要在UBL中修改这个函数,即按照芯片手册来配置DDR控制寄存器中的相关参数,比如时序,BANK数,页大小等。这个函数主要是操作SYS模块和DDR模块的相关寄存器来配置内存,函数中调用的DEVICE_LPSCTransition函数用来实现模块的电源时钟状态的改变,函数内容如下:
Uint32 DEVICE_DDR2Init() { DEVICE_LPSCTransition(LPSC_DDR2,0,PSC_ENABLE); SYSTEM->VTPIOCR = (SYSTEM->VTPIOCR) & 0xFFFF9F3F; // Set bit CLRZ (bit 13) SYSTEM->VTPIOCR = (SYSTEM->VTPIOCR) | 0x00002000; // Check VTP READY Status while( !(SYSTEM->VTPIOCR & 0x8000)); // Set bit VTP_IOPWRDWN bit 14 for DDR input buffers) //SYSTEM->VTPIOCR = SYSTEM->VTPIOCR | 0x00004000;
// Set bit LOCK(bit7) and PWRSAVE (bit8) SYSTEM->VTPIOCR = SYSTEM->VTPIOCR | 0x00000080; // Powerdown VTP as it is locked (bit 6) // Set bit VTP_IOPWRDWN bit 14 for DDR input buffers) SYSTEM->VTPIOCR = SYSTEM->VTPIOCR | 0x00004040; // Wait for calibration to complete UTIL_waitLoop( 150 ); // Set the DDR2 to synreset, then enable it again DEVICE_LPSCTransition(LPSC_DDR2,0,PSC_SYNCRESET); DEVICE_LPSCTransition(LPSC_DDR2,0,PSC_ENABLE); DDR->DDRPHYCR = 0x000000C5; DDR->SDBCR = 0x08D34832; //Program SDRAM Bank Config Register DDR->SDBCR = 0x0853C832; DDR->SDTIMR =0x3C934B51; //Program SDRAM Timing Control Register1 DDR->SDTIMR2 =0x4221C72; //Program SDRAM Timing Control Register2 DDR->PBBPR = 0x000000FE; DDR->SDBCR = 0x08534832; //Program SDRAM Bank Config Register DDR->SDRCR = 0x00000768; //Program SDRAM Refresh Control Register DEVICE_LPSCTransition(LPSC_DDR2,0,PSC_SYNCRESET); DEVICE_LPSCTransition(LPSC_DDR2,0,PSC_ENABLE); return E_PASS; }
void DEVICE_LPSCTransition(Uint8 module, Uint8 domain, Uint8 state) { // Wait for any outstanding transition to complete while ( (PSC->PTSTAT) & (0x00000001 << domain) ); // If we are already in that state, just return if (((PSC->MDSTAT[module]) & 0x1F) == state) return; // Perform transition PSC->MDCTL[module] = ((PSC->MDCTL[module]) & (0xFFFFFFE0)) | (state); PSC->PTCMD |= (0x00000001 << domain); // Wait for transition to complete while ( (PSC->PTSTAT) & (0x00000001 << domain) ); // Wait and verify the state while (((PSC->MDSTAT[module]) & 0x1F) != state); }
|
而后调用DEVICE_EMIFInit函数来配置EMIF模块,这个模块用来接外存,比如NAND,NOR等。DM365有两个片选空间,如果某一空间配置成NAND,则需要在寄存器中设置,其函数内容如下:
Uint32 DEVICE_EMIFInit() { AEMIF->AWCCR = 0xff; AEMIF->A1CR = 0x40400204; AEMIF->NANDFCR |= 1; AEMIF->A2CR = 0x00a00505; return E_PASS; }
|
而后调用DEVICE_UART0Init函数来配置串口0,调用DEVICE_TIMER0Init函数来配置TIMER0,调用DEVICE_I2C0Init函数来配置I2C控制器,都是操作某一模块的控制寄存器实现,具体如何设置可以参考相关模块的手册,这三个函数的内容如下:
Uint32 DEVICE_UART0Init() { UART0->PWREMU_MGNT = 0; // Reset UART TX & RX components
UTIL_waitLoop( 100 ); UART0->MDR = 0x0; UART0->DLL = 0xd; // Set baud rate UART0->DLH = 0; UART0->FCR = 0x0007; // Clear UART TX & RX FIFOs UART0->FCR = 0x0000; // Non-FIFO mode UART0->IER = 0x0007; // Enable interrupts
UART0->LCR = 0x0003; // 8-bit words // 1 STOP bit generated, // No Parity, No Stick paritiy, // No Break control UART0->MCR = 0x0000; // RTS & CTS disabled, // Loopback mode disabled, // Autoflow disabled UART0->PWREMU_MGNT = 0xE001; // Enable TX & RX componenets return E_PASS; }
Uint32 DEVICE_I2C0Init() { I2C0->ICMDR = 0; // Reset I2C I2C0->ICPSC = 26; // Config prescaler for 27MHz I2C0->ICCLKL = 20; // Config clk LOW for 20kHz I2C0->ICCLKH = 20; // Config clk HIGH for 20kHz I2C0->ICMDR |= I2C_ICMDR_IRS; // Release I2C from reset return E_PASS; }
Uint32 DEVICE_TIMER0Init() { // Put timer into reset TIMER0->EMUMGT_CLKSPD = 0x00000003; TIMER0->TCR = 0x00000000; // Enable TINT0, TINT1 interrupt TIMER0->INTCTL_STAT = 0x00000001; // Set to 64-bit GP Timer mode, enable TIMER12 & TIMER34 TIMER0->TGCR = 0x00000003; // Reset timers to zero TIMER0->TIM12 = 0x00000000; TIMER0->TIM34 = 0x00000000; // Set timer period (5 second timeout = (24000000 * 5) cycles = 0x07270E00) TIMER0->PRD34 = 0x00000000; TIMER0->PRD12 = 0x07270E00; return E_PASS; }
|
至此,DEVICE_init函数结束,程序返回至LOCAL_boot函数中,接着就调用NANDBOOT_copy函数了。
阅读(3112) | 评论(0) | 转发(0) |