Part Number: TMS320DM368
Hi,
My customer is using DM368, they have problem with NAND boot.
It is a problem that the DSP image can not be loaded correctly from NAND memory to DDR memory during UBL processing is executed.
This problem occurs rarely, and it is likely to occur in a high temperature.
However, this problem seems to be solved by inserting a wait after executing PLL1 initialization.
Please see the attached source file for the actual initialization processing, wait must be inserted between DEVICE_PLL1Init () and WDT_FLAG_ON ().
/* --------------------------------------------------------------------------
FILE : device.c
PROJECT : TI Booting and Flashing Utilities
AUTHOR : Sandeep Paulraj
DESC : This file provides low-level, device-specific init functions
for use the DM36x device.
-------------------------------------------------------------------------- */
// General type include
#include "tistdtypes.h"
// This module's header file
#include "device.h"
// Debug module
#include "debug.h"
// Utility functions
#include "util.h"
#include <stdio.h>
/************************************************************
* Explicit External Declarations *
************************************************************/
extern __FAR__ VUint32* DDRStart;
/************************************************************
* Local Macro Declarations *
************************************************************/
/************************************************************
* Local Typedef Declarations *
************************************************************/
/************************************************************
* Local Function Declarations *
************************************************************/
/************************************************************
* Local Variable Definitions *
\***********************************************************/
/************************************************************
* Global Variable Definitions *
************************************************************/
const String devString = "DM36x";
#define TMPBUF (unsigned int *)(0x0017ff8)
#define TMPSTATUS (unsigned int *)(0x0017ff0)
#define GPINT_GPEN (unsigned int *)(0x01C21C08) // WDT special function
#define GPTDAT_GPDIR (unsigned int *)(0x01C21C0c) // WDT special function
#define FLAG_PORRST (0x00000001)
#define FLAG_WDTRST (0x00000002)
#define FLAG_FLGON (0x00000004)
#define FLAG_FLGOFF (0x00000010)
/************************************************************
* Global Function Definitions *
************************************************************/
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
SYSTEM->PERI_CLKCTRL |= 1; //disable output 24Mhze
{
//Disable PSC
DRV_SyncRst(40, 0, 0);
DRV_SyncRst(2, 0, 0);
DRV_SyncRst(3, 0, 0);
DRV_SyncRst(4, 0, 0);
DRV_SyncRst(8, 0, 0);
DRV_SyncRst(44, 0, 0);
DRV_SyncRst(45, 0, 0);
DRV_SyncRst(46, 0, 0);
DRV_SyncRst(47, 0, 0);
DRV_SyncRst(50, 0, 0);
DRV_SyncRst(51, 0, 0);
UTIL_waitLoop (30000);
}
POR_RESET();
WDT_RESET();
// System PSC setup - enable all
DEVICE_PSCInit();
#if defined(IPNC_DM365) || defined(IPNC_DM368)
DEVICE_pinmuxControl(0,0xFFFFFFFF,0x00000000); //gio
DEVICE_pinmuxControl(1,0xFFFFFFFF,0x00430000); //gio
DEVICE_pinmuxControl(2,0xFFFFFFFF,0x00001980); //gio
DEVICE_pinmuxControl(3,0xFFFFFFFF,0x615AFFFF); //uart1 phy i2c
DEVICE_pinmuxControl(4,0xFFFFFFFF,0x0030c000); //clkout0 uar1
GPIO->DIR01 = 0xffffffff; //set all as input
GPIO->DIR23 = 0x3ef3ffff; //set nand_wp phy_rst led1 led2 as output
GPIO->SETDATA23 = 0x000c0000; //nand_wp phy_rst set hi
GPIO->CLRDATA23 = 0x01000000;//nand_ce low
GPIO->DIR45 = 0xf67dfffe; //cmos_rst as output
GPIO->SETDATA45 = 0x01800001; //led3_r on
GPIO->CLRDATA45 = 0x04000000; //cmos_rst = low
GPIO->DIR6 = 0xffffffff; //set all as input
{
unsigned int Counter,RegData,ClockIn;
Counter=0;
RegData=0;
ClockIn=1;
while(RegData ==0x10000 && Counter<0x1000){
Counter ++;
RegData=GPIO->INDTATA45 & 1<<16; //check 74.25 oscillator install(gio80) ?
}
if(Counter>=0x1000)
ClockIn=0;
while(RegData ==0 && Counter<0x1000){
Counter ++;
RegData=GPIO->INDTATA45 & 1<<16; //check 74.25 oscillator install(gio80) ?
}
if(Counter>=0x1000)
ClockIn=0;
while(RegData ==0x10000 && Counter<0x1000){
Counter ++;
RegData=GPIO->INDTATA45 & 1<<16; //check 74.25 oscillator install(gio80) ?
}
if(Counter>=0x1000)
ClockIn=0;
if(ClockIn)
DEVICE_pinmuxControl(1,3<<20,1<<20);
}
#else
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,0x375AFFFF); // SPI0, SPI1, UART1, I2C, SD0, SD1, McBSP0, CLKOUTs
DEVICE_pinmuxControl(4,0xFFFFFFFF,0x55555555); // MMC/SD0 instead of MS, SPI0
GPIO->DIR23 &= 0xfeffffff;
GPIO->CLRDATA23 = 0x01000000;
#endif
// System PLL setup
if (status == E_PASS) status |= DEVICE_PLL1Init();
WDT_FLAG_ON();
// 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();
#if defined(IPNC_DM365) || defined(IPNC_DM368)
SYSTEM->PERI_CLKCTRL &= ~1; //output 24Mhz
PLL1-> CKEN |= 0x2;
GPIO->SETDATA45 |= 0x04000000; //cmos_rst hi
// UART1 Setup
if (status == E_PASS) status |= DEVICE_UART1Init();
#endif
// 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;
}
Uint8 waitRtc(void)
{
Uint8 BusyState;
Uint32 RegVal,TimeOut;
BusyState = 1;
TimeOut = 0;
while( BusyState == 1 && TimeOut < 0x10000) {
TimeOut++;
RegVal = (CSL_RTSIF_0_REGS->DMACMD) & 0x80000000;
if ( RegVal == 0x00000000 ) {
BusyState = 0;
} else {
BusyState = 1;
}
}
return BusyState;
}
Uint8 RTCIF_setreg(Uint16 regnum, Uint8 regval)
{
Uint32 cmd = 0x00010000; // Command setting for one byte write
CSL_RTSIF_0_REGS->INTFLG = 1; // Clear interrupt flag
cmd += regnum; // Set register number in commmand
CSL_RTSIF_0_REGS->DMADAT0 = regval; // Value to write
CSL_RTSIF_0_REGS->DMACMD = cmd; // Write value
if(waitRtc()) // Wait for not busy
return 1;
return CSL_RTSIF_0_REGS->INTFLG;
}
Uint8 RTCIF_getreg(Uint16 regnum, Uint8 *regval)
{
Uint32 cmd = 0x01ff0000; // Command setting for 8 byte read
CSL_RTSIF_0_REGS->INTFLG = 1; // Clear interrupt flag
cmd += regnum; // Set register number in commmand
CSL_RTSIF_0_REGS->DMACMD = cmd; // Read value
if(waitRtc()) // Wait for not busy
return 1;
*regval = CSL_RTSIF_0_REGS->DMADAT0; // Send 1 byte of read value back
return CSL_RTSIF_0_REGS->INTFLG;
}
void POR_RESET()
{
Uint8 Val;
if ((PLL1->RSTYPE)&3) {
VPSS_HDVICP_SYNC_RESET();
*TMPBUF = 0;
*TMPSTATUS |= FLAG_PORRST;
*GPINT_GPEN = 0x00020000;
*GPTDAT_GPDIR = 0x00020002;
while(1);
}
waitRtc();
RTCIF_setreg(0x10,0);
RTCIF_getreg(0x10,&Val);
}
void WDT_RESET()
{
volatile unsigned int s;
if((*TMPBUF == 0x591b3ed7)){
*TMPBUF = 0;
*TMPSTATUS |= FLAG_PORRST;
*TMPSTATUS |= FLAG_FLGOFF;
for (s=0;s<0x100;s++) {}
VPSS_HDVICP_SYNC_RESET();
*GPINT_GPEN = 0x00020000; // WDT
*GPTDAT_GPDIR = 0x00020002; // execute >
while(1);
}
}
void VPSS_HDVICP_SYNC_RESET()
{
unsigned int PdNum = 0;
PLL1->PLLDIV4 = 0x8001; // DIV 1/2 -> EDMA/CONFIG
PLL1->PLLCMD = 0x00000001; // Go
//SYSTEM->VPSS_CLKCTL |= 0x00000080; // VPSS_CLKMD 1:1
//LPSC SyncReset DDR Clock Enable
PSC->MDCTL[47] = ((PSC->MDCTL[47] & 0xffffffe0) | 0x00000001);
PSC->PTCMD = (1<<PdNum);
while(! (((PSC->PTSTAT >> PdNum) & 0x00000001) == 0));
while(!((PSC->MDSTAT[47] & 0x0000001F) == 0x1));
//LPSC SyncReset DDR Clock Enable
PSC->MDCTL[51] = ((PSC->MDCTL[51] & 0xffffffe0) | 0x00000001);
PSC->PTCMD = (1<<PdNum);
while(! (((PSC->PTSTAT >> PdNum) & 0x00000001) == 0));
while(!((PSC->MDSTAT[51] & 0x0000001F) == 0x1));
}
void DRV_SyncRst(unsigned int module, unsigned int domain, unsigned int state)
{
int pMem_map;
unsigned int *pMDCTL = NULL;
unsigned int *pPTCMD = NULL;
unsigned int *pPTSTAT = NULL;
unsigned int *pMDSTAT = NULL;
pMem_map = 0x01C41000;
pPTCMD = (unsigned int *)( pMem_map+0x120 );
pPTSTAT = (unsigned int *)( pMem_map+0x128 );
pMDSTAT = (unsigned int *)( pMem_map+0x800 );
pMDCTL = (unsigned int *)( pMem_map+0xA00 );
// Wait for any outstanding transition to complete
while ( (*pPTSTAT) & (0x00000001 << domain) );
// If we are already in that state, just return
if (((pMDSTAT[module]) & 0x1F) == state) return;
// Perform transition
pMDCTL[module] = ((pMDCTL[module]) & (0xFFFFFFE0)) | (state);
*pPTCMD |= (0x00000001 << domain);
// Wait for transition to complete
while ( (*pPTSTAT) & (0x00000001 << domain) );
// Wait and verify the state
while (((pMDSTAT[module]) & 0x1F) != state);
return;
}
void WDT_FLAG_ON()
{
SYSTEM->VPSS_CLKCTL &= 0xffffff7f; // VPSS_CLKMD 1:2
*TMPBUF = 0x591b3ed7;
*TMPSTATUS |= FLAG_FLGON;
}
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);
}
void DEVICE_pinmuxControl(Uint32 regOffset, Uint32 mask, Uint32 value)
{
SYSTEM->PINMUX[regOffset] &= ~mask;
SYSTEM->PINMUX[regOffset] |= (mask & value);
}
DEVICE_BootMode DEVICE_bootMode( void )
{
return (DEVICE_BootMode) ((SYSTEM->BOOTCFG & DEVICE_BOOTCFG_BOOTMODE_MASK) >> DEVICE_BOOTCFG_BOOTMODE_SHIFT);
}
DEVICE_BusWidth DEVICE_emifBusWidth( void )
{
if ( ( (SYSTEM->BOOTCFG & DEVICE_BOOTCFG_EMIFWIDTH_MASK) >> DEVICE_BOOTCFG_EMIFWIDTH_SHIFT) & 0x1 )
{
return DEVICE_BUSWIDTH_16BIT;
}
else
{
return DEVICE_BUSWIDTH_8BIT;
}
}
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++) {
// CSL_FINS(CSL_PSC_0_REGS->MDCTL[i], PSC_MDCTL_NEXT, 0x3);
PSC->MDCTL[i] |= 0x3;
}
//Program goctl to start transition sequence for LPSCs
//CSL_PSC_0_REGS->PTCMD = (1<<PdNum); /*Kick off Power Domain 0 Modules*/
PSC->PTCMD = (1<<PdNum);
//Wait for GOSTAT = NO TRANSITION from PSC for Powerdomain 0
//while(! (((CSL_PSC_0_REGS->PTSTAT >> PdNum) & 0x00000001) == 0));
while(! (((PSC->PTSTAT >> PdNum) & 0x00000001) == 0));
//Wait for MODSTAT = ENABLE from LPSC's
for(i=lpsc_start; i<=lpsc_end; i++) {
// while(!((CSL_PSC_0_REGS->MDSTAT[i] & 0x0000001F) == 0x3));
while(!((PSC->MDSTAT[i] & 0x0000001F) == 0x3));
}
}
}
Uint32 DEVICE_PLL1Init()
{
unsigned int CLKSRC=0x0; /*CLKSRC=1 =>External Oscilator
CLKSRC=0 => Onchip oscilator */
/*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;
#ifdef IPNC_DM365
//Program the Multiper and Pre-Divider for PLL1
PLL1->PLLM = 0x2D; // M=45 ; VCO will 24*2M/N+1 = 540Mhz
PLL1->PREDIV = 0x8000|0x3; // N=3
PLL1->SECCTL = 0x00470000; // Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1
// for(j=0; j<0x100; j++) {}
PLL1->SECCTL = 0x00460000; // Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0
// for(j=0; j<0x100; j++) {}
PLL1->SECCTL = 0x00400000; // Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0
// for(j=0; j<0x100; j++) {}
PLL1->SECCTL = 0x00410000; // Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1
//Program the PostDiv for PLL1
PLL1->POSTDIV = 0x8000;
// Post divider setting for PLL1
PLL1->PLLDIV1 = 0x8015; // POST DIV 540/22=24.54 Mhz->USB PHY
PLL1->PLLDIV2 = 0x8001; //not use
PLL1->PLLDIV3 = 0x8001; // POST DIV 540/2 = 270Mhz -> MJCP/HDVICP
PLL1->PLLDIV4 = 0x8003; // POST DIV 540/4 = 135Mhz -> EDMA/Peripheral CFG0 (1/2 Kaleido clock)
PLL1->PLLDIV5 = 0x8001; // POST DIV 540/2 = 270Mhz -> VPSS (max 270)
PLL1->PLLDIV6 = 0x8013; // POST DIV 540/20 = 27Mhz -> VENC alternate for SD
PLL1->PLLDIV7 = 0x8000; // POST DIV 540/2 = 270Mhz -> DDR
PLL1->PLLDIV8 = 0x800A; // POST DIV 540/11 = 49.1Mhz-> MMC0/SD0
PLL1->PLLDIV9 = 0x8013; // POST DIV 540/20 = 27Mhz-> CLKOUT
#elif defined(IPNC_DM368)
#ifdef EXTREME
//Program the Multiper and Pre-Divider for PLL1
PLL1->PLLM = 0x1E; // M=30; VCO will 24*2M/N+1 = 720Mhz
PLL1->PREDIV = 0x8000|0x1; // N = 1
PLL1->SECCTL = 0x00470000; // Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1
// for(j=0; j<0x100; j++) {}
PLL1->SECCTL = 0x00460000; // Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0
// for(j=0; j<0x100; j++) {}
PLL1->SECCTL = 0x00400000; // Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0
// for(j=0; j<0x100; j++) {}
PLL1->SECCTL = 0x00410000; // Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1
//Program the PostDiv for PLL1
PLL1->POSTDIV = 0x8000;
// Post divider setting for PLL1
PLL1->PLLDIV1 = 0x8019; //POST DIV 720/26=27.7 Mhz->USB PHY
PLL1->PLLDIV2 = 0x8001; //POST DIV 720/2=360Mhz->ARM926/ARM968
PLL1->PLLDIV3 = 0x8001; // POST DIV 720/2 = 360Mhz -> MJCP/HDVICP
PLL1->PLLDIV4 = 0x8003; // POST DIV 720/4 = 180Mhz -> EDMA/Peripheral CFG0 (1/2 Kaleido clock)
PLL1->PLLDIV5 = 0x8001; // POST DIV 720/2 = 360Mhz -> VPSS (max 270)
PLL1->PLLDIV6 = 0x8009; // POST DIV 720/10 = 72Mhz -> VENC
PLL1->PLLDIV7 = 0x8000; // POST DIV 720/1 = 720Mhz -> DDRx2
PLL1->PLLDIV8 = 0x800E; // POST DIV 720/15 = 48Mhz-> MMC0/SD0
PLL1->PLLDIV9 = 0x8019; // POST DIV 720/26 = 27.7Mhz-> CLKOUT
#else
//Program the Multiper and Pre-Divider for PLL1
PLL1->PLLM = 85; // M=85; VCO will 24*2M/N+1 = 680Mhz
PLL1->PREDIV = 0x8000|0x5; // N = 5
PLL1->SECCTL = 0x00470000; // Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1
// for(j=0; j<0x100; j++) {}
PLL1->SECCTL = 0x00460000; // Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0
// for(j=0; j<0x100; j++) {}
PLL1->SECCTL = 0x00400000; // Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0
// for(j=0; j<0x100; j++) {}
PLL1->SECCTL = 0x00410000; // Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1
//Program the PostDiv for PLL1
PLL1->POSTDIV = 0x8000;
// Post divider setting for PLL1
PLL1->PLLDIV1 = 0x801B; //POST DIV 680/28=24.3 Mhz->USB PHY
PLL1->PLLDIV2 = 0x8001; //POST DIV 680/2=340Mhz->ARM926/ARM968
PLL1->PLLDIV3 = 0x8001; // POST DIV 680/2 = 340Mhz -> MJCP/HDVICP
PLL1->PLLDIV4 = 0x8003; // POST DIV 680/4 = 170Mhz -> EDMA/Peripheral CFG0 (1/2 Kaleido clock)
PLL1->PLLDIV5 = 0x8001; // POST DIV 680/2 = 340Mhz -> VPSS (max 270)
PLL1->PLLDIV6 = 0x8008; // POST DIV 680/9 = 75.6Mhz -> VENC
PLL1->PLLDIV7 = 0x8000; // POST DIV 680/1 = 680Mhz -> DDRx2
PLL1->PLLDIV8 = 0x800D; // POST DIV 680/14= 48.6Mhz-> MMC0/SD0
PLL1->PLLDIV9 = 0x801B; // POST DIV 680/28 = 24.3Mhz-> CLKOUT
#endif
#else
#error Not define a platform
#endif
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;
}
Uint32 DEVICE_PLL2Init()
{
unsigned int CLKSRC=0x0;
/*Power up the PLL*/
PLL2->PLLCTL &= 0xFFFFFFFD;
/*Select the Clock Mode as Onchip Oscilator or External Clock on MXI pin*/
/*VDB has input on MXI pin */
PLL2->PLLCTL &= 0xFFFFFEFF;
PLL2->PLLCTL |= CLKSRC<<8;
/*Set PLLENSRC '0', PLL Enable(PLLEN) selection is controlled through MMR*/
PLL2->PLLCTL &= 0xFFFFFFDF;
/*Set PLLEN=0 => PLL BYPASS MODE*/
PLL2->PLLCTL &= 0xFFFFFFFE;
UTIL_waitLoop(50);
// PLLRST=1(reset assert)
PLL2->PLLCTL |= 0x00000008;
UTIL_waitLoop(300);
/*Bring PLL out of Reset*/
PLL2->PLLCTL &= 0xFFFFFFF7;
#ifdef IPNC_DM365
//Program the Multiper and Pre-Divider for PLL2
PLL2->PLLM = 0x63; // VCO will 24*2M/N+1 = 594Mhz
PLL2->PREDIV = 0x8000|0x7;
PLL2->POSTDIV = 0x8000;
PLL2->SECCTL = 0x00470000; // Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1
PLL2->SECCTL = 0x00460000; // Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0
PLL2->SECCTL = 0x00400000; // Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0
PLL2->SECCTL = 0x00410000; // Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1
// Post divider setting for PLL2
PLL2->PLLDIV1 = 0x801E; // 594/31=19.16 Mhz ->USB PHY
PLL2->PLLDIV2 = 0x8001; // 594/2 =297 Mhz -> ARM
PLL2->PLLDIV3 = 0x8001; // POST DIV 594/2=297 Mhz -> DDRx2
PLL2->PLLDIV4 = 0x8004; // POST DIV 594/5=118.8 Mhz -> VOICE
PLL2->PLLDIV5 = 0x8007; // POST DIV 594/8 = 74.25 Mhz ->VIDEO HD
//GoCmd for PostDivider to take effect
PLL2->PLLCMD = 0x00000001;
UTIL_waitLoop(150);
/*Wait for PLL to LOCK */
while(! (((SYSTEM->PLL1_CONFIG) & 0x07000000) == 0x07000000));
UTIL_waitLoop(4100);
//Enable the PLL2
PLL2->PLLCTL |= 0x00000001; // PLLEN=0
//do this after PLL's have been set up
SYSTEM->PERI_CLKCTRL = 0x36ED0E7C; //sample rate 2.048Mhz
#elif defined(IPNC_DM368)
#ifdef EXTREME
//Program the Multiper and Pre-Divider for PLL2
PLL2->PLLM = 0x51; // M=81; VCO will 24*2M/N+1 = 486Mhz
PLL2->PREDIV = 0x8000 | 0x7; // N = 7
PLL2->POSTDIV = 0x8000;
PLL2->SECCTL = 0x00470000; // Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1
PLL2->SECCTL = 0x00460000; // Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0
PLL2->SECCTL = 0x00400000; // Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0
PLL2->SECCTL = 0x00410000; // Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1
// Post divider setting for PLL2
PLL2->PLLDIV1 = 0x8011; // POST DIV 486/18=27 Mhz ->USB PHY
PLL2->PLLDIV2 = 0x8000; // POST DIV 486/1=486 Mhz -> ARM926/HDVICP Cont
PLL2->PLLDIV3 = 0x8001; // POST DIV 486/2=243 Mhz -> DDRx2
PLL2->PLLDIV4 = 0x8010; // POST DIV 486/17= 28.59 Mhz->VOICE
PLL2->PLLDIV5 = 0x8011; // POST DIV 486/18=27 Mhz -> VENC
PLL2->PLLCMD = 0x00000001;
UTIL_waitLoop(150);
/*Wait for PLL to LOCK */
while(! (((SYSTEM->PLL1_CONFIG) & 0x07000000) == 0x07000000));
UTIL_waitLoop(4100);
//Enable the PLL2
PLL2->PLLCTL |= 0x00000001; // PLLEN=0
//do this after PLL's have been set up
SYSTEM->PERI_CLKCTRL = 0x36ED037C;
#else
//Program the Multiper and Pre-Divider for PLL2
PLL2->PLLM = 9; // M=135; VCO will 24*2M/N+1 = 432Mhz
PLL2->PREDIV = 0x8000| 0x0; // N = 0
PLL2->POSTDIV = 0x8000;
PLL2->SECCTL = 0x00470000; // Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1
PLL2->SECCTL = 0x00460000; // Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0
PLL2->SECCTL = 0x00400000; // Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0
PLL2->SECCTL = 0x00410000; // Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1
// Post divider setting for PLL2
PLL2->PLLDIV1 = 0x8011; // POST DIV 432/18=24 Mhz ->USB PHY
PLL2->PLLDIV2 = 0x8000; // POST DIV 432/1=432 Mhz -> ARM926/HDVICP Cont
PLL2->PLLDIV3 = 0x8001; // POST DIV 432/2=216 Mhz -> DDRx2
PLL2->PLLDIV4 = 0x8014; // POST DIV 432/21= 20.5714 Mhz->VOICE
PLL2->PLLDIV5 = 0x800F; // POST DIV 432/16=27 Mhz -> VENC
PLL2->PLLCMD = 0x00000001;
UTIL_waitLoop(150);
/*Wait for PLL to LOCK */
while(! (((SYSTEM->PLL1_CONFIG) & 0x07000000) == 0x07000000));
UTIL_waitLoop(4100);
//Enable the PLL2
PLL2->PLLCTL |= 0x00000001; // PLLEN=0
//do this after PLL's have been set up
SYSTEM->PERI_CLKCTRL = 0x36ED027C;
#endif
#else
#error Not define a platform
#endif
return E_PASS;
}
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 = 0x000000C6;
DDR->SDBCR = 0x00D34A32; //Program SDRAM Bank Config Register
DDR->SDBCR = 0x0053CA32;
#ifdef IPNC_DM365
DDR->SDTIMR =0x44DC63D2; //Program SDRAM Timing Control Register1
DDR->SDTIMR2 =0x4225C742; //Program SDRAM Timing Control Register2
DDR->PBBPR = 0x000000F0;
DDR->SDBCR = 0x00534A32; //Program SDRAM Bank Config Register
DDR->SDRCR = 0x83A; //Program SDRAM Refresh Control Register
#elif defined(IPNC_DM368)
#ifdef EXTREME
DDR->SDTIMR = 0x5B258512; //Program SDRAM Timing Control Register1
DDR->SDTIMR2 = 0x4231C742; //Program SDRAM Timing Control Register2
DDR->PBBPR = 0x000000F0;
DDR->SDBCR = 0x00534A32; //Program SDRAM Bank Config Register
DDR->SDRCR = 0xAF8; //Program SDRAM Refresh Control Register
#else
DDR->SDTIMR =0x57257CD2; //Program SDRAM Timing Control Register1
DDR->SDTIMR2 =0x422EC742; //Program SDRAM Timing Control Register2
DDR->PBBPR = 0x000000F0;
DDR->SDBCR = 0x00534A32; //Program SDRAM Bank Config Register
DDR->SDRCR = 0xA5C; //Program SDRAM Refresh Control Register
#endif
#else
#error Not define a platform
#endif
DEVICE_LPSCTransition(LPSC_DDR2,0,PSC_SYNCRESET);
DEVICE_LPSCTransition(LPSC_DDR2,0,PSC_ENABLE);
while(!(DDR->SDRSTAT&0x04));
return E_PASS;
}
Uint32 DEVICE_EMIFInit()
{
AEMIF->AWCCR = 0xff;
#ifdef IPNC_DM365
AEMIF->A1CR = 0x40800080; //for 121.5 MHZ
#elif defined(IPNC_DM368)
AEMIF->A1CR = 0x5030420C; //for 170 MHZ
#endif
AEMIF->NANDFCR |= 1;
AEMIF->A2CR = 0x00a00505;
return E_PASS;
}
Uint32 DEVICE_UART1Init()
{
Uint32 divider,pll1_clk;
//divider = DEVICE_OSC_FREQ / (DEVICE_UART0_DESIRED_BAUD * DEVICE_UART0_OVERSAMPLE_CNT);
pll1_clk = ((PLL1->PLLM & 0x1ff) *2*24)/((PLL1->PREDIV & 0x1F) + 1)/((PLL1->POSTDIV & 0x1F) + 1);
divider = (pll1_clk/4)*1000000/(16*115200);
UART1->PWREMU_MGNT = 0; // Reset UART TX & RX components
UTIL_waitLoop( 100 );
UART1->MDR = 0x0;
UART1->DLL = divider; // Set baud rate
UART1->DLH = 0;
UART1->FCR = 0x0007; // Clear UART TX & RX FIFOs
UART1->FCR = 0x0000; // Non-FIFO mode
UART1->IER = 0x0007; // Enable interrupts
UART1->LCR = 0x0003; // 8-bit words,
// 1 STOP bit generated,
// No Parity, No Stick paritiy,
// No Break control
UART1->MCR = 0x0000; // RTS & CTS disabled,
// Loopback mode disabled,
// Autoflow disabled
UART1->PWREMU_MGNT = 0xE001; // Enable TX & RX componenets
return E_PASS;
}
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_I2C0Reset()
{
I2C0->ICMDR &= ~I2C_ICMDR_IRS;
UTIL_waitLoop(200);
// Read and clear interrupt status register
I2C0->ICSTR |= 0x00007FFF;
// Read ICIVR until clear
while ((I2C0->ICIVR & 0x7) != 0x0);
// Take I2C Out of Reset
I2C0->ICMDR |= I2C_ICMDR_IRS;
UTIL_waitLoop(200);
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;
}
Uint32 DEVICE_TIMER1Init()
{
// Put timer into reset
TIMER1->EMUMGT_CLKSPD = 0x00000003;
TIMER1->TGCR = 0x00000000;
// Enable TINT0, TINT1 interrupt
TIMER1->INTCTL_STAT = 0x00000001;
// Set to 64-bit GP Timer mode, enable TIMER12 & TIMER34
TIMER1->TGCR = 0x00000003;
// Reset timers to zero
TIMER1->TIM12 = 0x00000000;
TIMER1->TIM34 = 0x00000000;
// Set timer period (5 second timeout = (24000000 * 5) cycles = 0x07270E00)
TIMER1->PRD34 = 0xFFFFFFFF;
TIMER1->PRD12 = 0xFFFFFFFF;
AINTC->IRQ1 |= 0x00000001;
TIMER1->TCR = 0x00000040;
return E_PASS;
}
//interrupt for Timer0 in DM35x and DM36x is the same
void DEVICE_TIMER0Start(void)
{
// Clear interrupt
AINTC->IRQ1 |= 0x00000001;
// Put timer in reset
TIMER0->TGCR = 0x00000000;
// Reset timer count to zero
TIMER0->TIM12 = 0x00000000;
// Setup for one-shot mode
TIMER0->TCR = 0x00000040;
// Start TIMER12
TIMER0->TGCR = 0x00000005;
}
void DEVICE_TIMER0Stop(void)
{
// Clear interrupt
AINTC->IRQ1 |= 0x00000001;
// Put timer in reset
TIMER0->TCR = 0x00000000;
TIMER0->TGCR = 0x00000000;
// Reset timer count to zero
TIMER0->TIM12 = 0x00000000;
}
Uint32 DEVICE_TIMER0Status(void)
{
return ((AINTC->IRQ1)&0x1);
}
#define TIMER1_TICK_COUNT 24000
Uint32 DEVICE_TIMER1GetTime()
{
Uint32 tim12_val;
tim12_val = TIMER1->TIM12;
return ((tim12_val) / TIMER1_TICK_COUNT);
}
/************************************************************
* Local Function Definitions *
************************************************************/
/***********************************************************
* End file *
***********************************************************/
== device.c ==
if (status == E_PASS) status |= DEVICE_PLL1Init();
"Insert Wait"
WDT_FLAG_ON();
===============
It is changed from bypass mode to PLL mode at the end of the PLL initialization procedure, I think that the CPU is unstable after transition to PLL mode.
So I think wait must insert it, do I understand correctly?
Best regards,
H.U
