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

📄 dm644x.c

📁 TI DM6446 EVM 串口下载程序 使用环境:windows dos环境或者linux 使用前需安装mono
💻 C
字号:
/* --------------------------------------------------------------------------
    FILE        : dm644x.c 				                             	 	        
    PURPOSE     : Platform initialization file
    PROJECT     : DaVinci User Boot-Loader and Flasher
    AUTHOR      : Daniel Allred
    DATE	    : Jan-22-2007  
 
    HISTORY
 	     v1.00 completion (with support for DM6441 and DM6441_LV)							 						      
 	          Daniel Allred - Jan-22-2007
 ----------------------------------------------------------------------------- */

#include "dm644x.h"
#include "ubl.h"
#include "uart.h"

extern VUint32 DDRMem[0];
extern BootMode gBootMode;
extern Uint32 gEntryPoint;

// ---------------------------------------------------------------------------
// Global Memory Timing and PLL Settings
// ---------------------------------------------------------------------------
#if defined(DM6441_LV)
    // For Micron MT47H64M16BT-37E @ 135 MHz   
    Uint8 DDR_NM = 0;
    Uint8 DDR_CL = 3;
    Uint8 DDR_IBANK = 3;
    Uint8 DDR_PAGESIZE = 2;
    Uint8 DDR_T_RFC = 17;
    Uint8 DDR_T_RP = 2;
    Uint8 DDR_T_RCD = 2;
    Uint8 DDR_T_WR = 2;
    Uint8 DDR_T_RAS = 5;
    Uint8 DDR_T_RC = 7;
    Uint8 DDR_T_RRD = 1;
    Uint8 DDR_T_WTR = 1;
    Uint8 DDR_T_XSNR = 18;
    Uint8 DDR_T_XSRD = 199;
    Uint8 DDR_T_RTP = 1;
    Uint8 DDR_T_CKE = 2;
    Uint16 DDR_RR = 1264;
    Uint8 DDR_Board_Delay = 3;
    Uint8 DDR_READ_Latency = 5;
    
    Uint32 PLL2_Mult = 20;
    Uint32 PLL2_Div1 = 10;
    Uint32 PLL2_Div2 = 2;
#else
    // For Micron MT47H64M16BT-37E @ 162 MHz
    Uint8 DDR_NM = 0;
    Uint8 DDR_CL = 3;
    Uint8 DDR_IBANK = 3;
    Uint8 DDR_PAGESIZE = 2;
    Uint8 DDR_T_RFC = 20;
    Uint8 DDR_T_RP = 2;
    Uint8 DDR_T_RCD = 2;
    Uint8 DDR_T_WR = 2;
    Uint8 DDR_T_RAS = 6;
    Uint8 DDR_T_RC = 8;
    Uint8 DDR_T_RRD = 2;
    Uint8 DDR_T_WTR = 1;
    Uint8 DDR_T_XSNR = 22;
    Uint8 DDR_T_XSRD = 199;
    Uint8 DDR_T_RTP = 1;
    Uint8 DDR_T_CKE = 2;
    Uint16 DDR_RR = 1053;
    Uint8 DDR_Board_Delay = 3;
    Uint8 DDR_READ_Latency = 5; 
    
    Uint32 PLL2_Mult = 24;
    Uint32 PLL2_Div1 = 12;
    Uint32 PLL2_Div2 = 2;
    
    // 567 verison - only use this with older silicon/EVMs
    // For Micron MT47H64M16BT-37E @ 189 MHz
    /*Uint8 DDR_NM = 0;
    Uint8 DDR_CL = 4;
    Uint8 DDR_IBANK = 3;
    Uint8 DDR_PAGESIZE = 2;
    Uint8 DDR_T_RFC = 24;
    Uint8 DDR_T_RP = 2;
    Uint8 DDR_T_RCD = 2;
    Uint8 DDR_T_WR = 2;
    Uint8 DDR_T_RAS = 7;
    Uint8 DDR_T_RC = 10;
    Uint8 DDR_T_RRD = 2;
    Uint8 DDR_T_WTR = 1;
    Uint8 DDR_T_XSNR = 25;
    Uint8 DDR_T_XSRD = 199;
    Uint8 DDR_T_RTP = 1;
    Uint8 DDR_T_CKE = 2;
    Uint16 DDR_RR = 1477;
    Uint8 DDR_Board_Delay = 2;
    Uint8 DDR_READ_Latency = 5;
    
    Uint32 PLL2_Mult = 14;
    Uint32 PLL2_Div1 = 7;
    Uint32 PLL2_Div2 = 1;*/
#endif

// Set CPU clocks
#if defined(DM6441_LV)
    Uint32 PLL1_Mult = 15;  // DSP=405 MHz
#elif defined(DM6441)
    Uint32 PLL1_Mult = 19;  // DSP=513 MHz  
#else
    Uint32 PLL1_Mult = 22;  // DSP=594 MHz
    // 567 version - only use this with older silicon/EVMs
    // Uint32 PLL1_Mult = 21;
#endif
           
    
    
// ---------------------------------------------------------
// End of global PLL and Memory settings
// ---------------------------------------------------------
    

void LPSCTransition(Uint8 module, Uint8 state)
{
    while (PSC->PTSTAT & 0x00000001);
	PSC->MDCTL[module] = ((PSC->MDCTL[module]) & (0xFFFFFFE0)) | (state);
	PSC->PTCMD |= 0x00000001;
	while ((PSC->PTSTAT) & 0x00000001);
	while (((PSC->MDSTAT[module]) & 0x1F) != state);	
}
	
void DM644xInit()
{
	// Mask all interrupts
	AINTC->INTCTL = 0x0;
	AINTC->EINT0 = 0x0;
	AINTC->EINT1 = 0x0;		
	
	// Put the C64x+ Core into reset (if it's on)
	PSC->MDCTL[39] &= (~0x00000100);
	PSC->PTCMD |= 0x00000002;
	while ((PSC->PTSTAT) & (0x00000002));
	while ((PSC->MDSTAT[39]) & (0x00000100));
	
	/******************* UART Setup **************************/
	UARTInit();
	
	/******************* System PLL Setup ********************/
	PLL1Init();
	
	/******************* DDR PLL Setup ***********************/	
	PLL2Init();

	/******************* DDR2 Timing Setup *******************/
	DDR2Init();
			
	/******************* AEMIF Setup *************************/
	//AEMIFInit();
    
    /******************* IRQ Vector Table Setup **************/
    IVTInit();
}

void PLL2Init()
{	
    // 162 MHz DDR
//    Uint32 PLL2_Mult = 24;
//    Uint32 PLL2_Div1 = 12;
//    Uint32 PLL2_Div2 = 2;
    
    // 567 verison - only use this with older silicon/EVMs
    // 189 MHz DDR
    /*Uint32 PLL2_Mult = 14;
    Uint32 PLL2_Div1 = 7;
    Uint32 PLL2_Div2 = 1;*/
    
        
	// Set PLL2 clock input to external osc. 
	PLL2->PLLCTL &= (~0x00000100);
	
	// Clear PLLENSRC bit and clear PLLEN bit for Bypass mode 
	PLL2->PLLCTL &= (~0x00000021);

	// Wait for PLLEN mux to switch 
	waitloop(32*(PLL1_Mult/2));
	
	PLL2->PLLCTL &= (~0x00000008);          // Put PLL into reset
	PLL2->PLLCTL |= (0x00000010);           // Disable the PLL
	PLL2->PLLCTL &= (~0x00000002);          // Power-up the PLL
	PLL2->PLLCTL &= (~0x00000010);          // Enable the PLL
	
	// Set PLL multipliers and divisors 
	PLL2->PLLM      = PLL2_Mult-1;     // 27  Mhz * (23+1) = 648 MHz 
	PLL2->PLLDIV1   = PLL2_Div1-1;     // 648 MHz / (11+1) = 54  MHz
	PLL2->PLLDIV2   = PLL2_Div2-1;     // 648 MHz / (1+1 ) = 324 MHz (the PHY DDR rate)
		
	PLL2->PLLDIV2 |= (0x00008000);          // Enable DDR divider	
	PLL2->PLLDIV1 |= (0x00008000);          // Enable VPBE divider	
	PLL2->PLLCMD |= 0x00000001;             // Tell PLL to do phase alignment
	while ((PLL2->PLLSTAT) & 0x1);          // Wait until done
	waitloop(256*(PLL1_Mult/2));

	PLL2->PLLCTL |= (0x00000008);           // Take PLL out of reset	
	waitloop(2000*(PLL1_Mult/2));                       // Wait for locking
	
	PLL2->PLLCTL |= (0x00000001);           // Switch out of bypass mode
}

void DDR2Init()
{
    
    // For Micron MT47H64M16BT-37E @ 162 MHz
    //Uint8 DDR_NM = 0;
    //Uint8 DDR_CL = 3;
    //Uint8 DDR_IBANK = 3;
    //Uint8 DDR_PAGESIZE = 2;
    //Uint8 DDR_T_RFC = 20;
    //Uint8 DDR_T_RP = 2;
    //Uint8 DDR_T_RCD = 2;
    //Uint8 DDR_T_WR = 2;
    //Uint8 DDR_T_RAS = 6;
    //Uint8 DDR_T_RC = 8;
    //Uint8 DDR_T_RRD = 2;
    //Uint8 DDR_T_WTR = 1;
    //Uint8 DDR_T_XSNR = 22;
    //Uint8 DDR_T_XSRD = 199;
    //Uint8 DDR_T_RTP = 1;
    //Uint8 DDR_T_CKE = 2;
    //Uint16 DDR_RR = 1264;
    //Uint8 DDR_Board_Delay = 3;
    //Uint8 DDR_READ_Latency = DDR_CL+DDR_Board_Delay-1;
    //   
    
    // For Micron MT47H64M16BT-37E @ 189 MHz
    /*Uint8 DDR_NM = 0;
    Uint8 DDR_CL = 4;
    Uint8 DDR_IBANK = 3;
    Uint8 DDR_PAGESIZE = 2;
    Uint8 DDR_T_RFC = 24;
    Uint8 DDR_T_RP = 2;
    Uint8 DDR_T_RCD = 2;
    Uint8 DDR_T_WR = 2;
    Uint8 DDR_T_RAS = 7;
    Uint8 DDR_T_RC = 10;
    Uint8 DDR_T_RRD = 2;
    Uint8 DDR_T_WTR = 1;
    Uint8 DDR_T_XSNR = 25;
    Uint8 DDR_T_XSRD = 199;
    Uint8 DDR_T_RTP = 1;
    Uint8 DDR_T_CKE = 2;
    Uint16 DDR_RR = 1477;
    Uint8 DDR_Board_Delay = 2;
    Uint8 DDR_READ_Latency = DDR_CL+DDR_Board_Delay-1;*/
    
	Int32 tempVTP;
	
	// Set the DDR2 to enable
	LPSCTransition(LPSC_DDR2, PSC_ENABLE);
		
	// For Micron MT47H64M16BT-37E @ 162 MHz
	// Setup the read latency (CAS Latency + 3 = 6 (but write 6-1=5))
	//DDR->DDRPHYCR = 0x14001905;
	DDR->DDRPHYCR = 0x14001900 | DDR_READ_Latency;
	// Set TIMUNLOCK bit, CAS LAtency 3, 8 banks, 1024-word page size 
	//DDR->SDBCR = 0x00138632;
	DDR->SDBCR = 0x00138000 |
	             (DDR_NM << 14)   |
	             (DDR_CL << 9)    |
	             (DDR_IBANK << 4) |
	             (DDR_PAGESIZE <<0);
	
	// Program timing registers 
	//DDR->SDTIMR = 0x28923211;
	DDR->SDTIMR = (DDR_T_RFC << 25) |              
                  (DDR_T_RP << 22)  |
                  (DDR_T_RCD << 19) |
                  (DDR_T_WR << 16)  |
                  (DDR_T_RAS << 11) |
                  (DDR_T_RC << 6)   |
                  (DDR_T_RRD << 3)  |
                  (DDR_T_WTR << 0);
	//DDR->SDTIMR2 = 0x0016C722;
	DDR->SDTIMR2 = (DDR_T_XSNR << 16) |
                   (DDR_T_XSRD << 8)  |
                   (DDR_T_RTP << 5)   |
                   (DDR_T_CKE << 0);
    
    // Clear the TIMUNLOCK bit 
	DDR->SDBCR &= (~0x00008000);
	
	// Set the refresh rate
	DDR->SDRCR = DDR_RR;
	
	// Dummy write/read to apply timing settings
	DDRMem[0] = DDR_TEST_PATTERN;
	if (DDRMem[0] == DDR_TEST_PATTERN)
          UARTSendInt(DDRMem[0]);
	
	// Set the DDR2 to syncreset
	LPSCTransition(LPSC_DDR2, PSC_SYNCRESET);

	// Set the DDR2 to enable
	LPSCTransition(LPSC_DDR2, PSC_ENABLE);
	
			 
	/***************** DDR2 VTP Calibration ****************/
	DDR->VTPIOCR = 0x201F;        // Clear calibration start bit
	DDR->VTPIOCR = 0xA01F;        // Set calibration start bit 
	
	waitloop(11*33);              // Wait for calibration to complete 
		 
	SYSTEM->DDRVTPER = 0x1;       // DDRVTPR Enable register
	
	tempVTP = 0x3FF & DDRVTPR;    // Read calibration data
	
	// Write calibration data to VTP Control register 
	DDR->VTPIOCR = ((DDR->VTPIOCR) & 0xFFFFFC00) | tempVTP; 
	
	// Clear calibration enable bit
	DDR->VTPIOCR = (DDR->VTPIOCR) & (~0x00002000);
	
	// DDRVTPR Enable register - disable DDRVTPR access 
	SYSTEM->DDRVTPER = 0x0;
	
}

void PLL1Init()
{
    //594 version
    //Uint32 PLL1_Mult = 22;
        
    //567 version - use with 189 MHZ DDR
    //Uint32 PLL1_Mult = 21;
            
	// Set PLL2 clock input to internal osc. 
	PLL1->PLLCTL &= (~0x00000100);	
	
	// Clear PLLENSRC bit and clear PLLEN bit for Bypass mode 
	PLL1->PLLCTL &= (~0x00000021);

	// Wait for PLLEN mux to switch 
	waitloop(32);
	
	PLL1->PLLCTL &= (~0x00000008);     // Put PLL into reset
	PLL1->PLLCTL |= (0x00000010);      // Disable the PLL
	PLL1->PLLCTL &= (~0x00000002);     // Power-up the PLL
	PLL1->PLLCTL &= (~0x00000010);     // Enable the PLL
	
	// Set PLL multipliers and divisors 
	PLL1->PLLM = PLL1_Mult - 1;        // 27Mhz * (21+1) = 594 MHz 
			
	PLL1->PLLCMD |= 0x00000001;		// Tell PLL to do phase alignment
	while ((PLL1->PLLSTAT) & 0x1);	// Wait until done
	
	waitloop(256);
	PLL1->PLLCTL |= (0x00000008);		//	Take PLL out of reset	
	waitloop(2000);				// Wait for locking
	
	PLL1->PLLCTL |= (0x00000001);		// Switch out of bypass mode
}
/* 
void AEMIFInit()
{     
   AEMIF->AWCCR     = 0x00000000;
   AEMIF->AB1CR     = 0x3FFFFFFD;
   AEMIF->AB2CR     = 0x3FFFFFFD;
   AEMIF->AB3CR     = 0x3FFFFFFD;
   AEMIF->AB4CR     = 0x3FFFFFFD;
   AEMIF->NANDFCR   = 0x00000000;
}*/
 
void UARTInit()
{		
    // The DM644x pin muxing registers must be set for UART0 use. 
	SYSTEM->PINMUX[1] |=  1;
	
	// Set DLAB bit - allows setting of clock divisors 
	UART0->LCR |= 0x80;
	
	//divider = 27000000/(16*115200) = 14.64 => 15 = 0x0F (2% error is OK)
	UART0->DLL = 0x0F;
	UART0->DLH = 0x00; 

    // Enable, clear and reset FIFOs	
	UART0->FCR = 0x07;
	
	// Disable autoflow control 
	UART0->MCR = 0x00;
	
	// Enable receiver, transmitter, st to run. 
	UART0->PWREMU_MGNT |= 0x6001;
	//UART0->PWREMU_MGNT |= 0x8001;

	// Set word length to 8 bits, clear DLAB bit 
	UART0->LCR = 0x03;

	// Disable the timer 
	TIMER0->TCR = 0x00000000;
	// Set to 64-bit GP Timer mode, enable TIMER12 & TIMER34
	TIMER0->TGCR = 0x00000003;

	// Reset timers to zero 
	TIMER0->TIM34 = 0x00000000;
	TIMER0->TIM12 = 0x00000000;
	
	// Set timer period (5 second timeout = (27000000 * 5) cycles = 0x080BEFC0) 
	TIMER0->PRD34 = 0x00000000;
	TIMER0->PRD12 = 0x080BEFC0;
}

void IVTInit()
{
	VUint32 *ivect;
    extern Uint32 __IVT;
    
	if (gBootMode == NON_SECURE_NOR)
	{
		ivect = &(__IVT);
		*ivect++ = 0xEAFFFFFE;  /* Reset @ 0x00*/
	}
	else
	{
		ivect = &(__IVT) + 4;
	}
	*ivect++ = 0xEAFFFFFE;  /* Undefined Address @ 0x04 */
	*ivect++ = 0xEAFFFFFE;  /* Software Interrupt @0x08 */
	*ivect++ = 0xEAFFFFFE;  /* Pre-Fetch Abort @ 0x0C */
	*ivect++ = 0xEAFFFFFE;  /* Data Abort @ 0x10 */
	*ivect++ = 0xEAFFFFFE;  /* Reserved @ 0x14 */
	*ivect++ = 0xEAFFFFFE;  /* IRQ @ 0x18 */
	*ivect   = 0xEAFFFFFE;	/* FIQ @ 0x1C */
}

⌨️ 快捷键说明

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