创龙TL6748开发板中,EMIFA模块使用默认的PLL0_SYSCLK3时钟,使用AISgen for D800K008工具加载C6748配置文件C6748AISgen_456M_config(Configuration files,在TL_TMS6748/images文件夹下),由图可以看到DIV3等于4,注意这里的DIV3就是实际的分频值(x),而不是写入相应PLL寄存器的值(x-1)。
(Using the TMS320C6748C6746C6742 Bootloader (Rev. F)P15)
因此在设置CPU主频为456MHz的情况下,PLL0_SYSCLK1等于456MHz,PLL0_SYSCLK3应该等于PLL0_SYSCLK1/4(456MHz/4=114MHz),即114MHz。在默认情况下,EMIFA时钟输入来自PLL0_SYSCLK3(见下图),因此EMIFA模块时钟EMA_CLK应为114MHz,而不是程序代码所注释的91MHz。
// NAND
模块时钟
#defineNAND_MODULE_CLK ((91u)*(1000u)*(1000u))
#defineNAND_MODULE_CLK_IN_MHZ (NAND_MODULE_CLK
/1000000)
(手册P90)
上面说的是用BootLoader脚本工具AISgen for D800K008生成固件(.ais文件)中初始化代码(即启动代码,BootLoader) 情况下,使用创龙提供的配置文件EMIFA模块的时钟。这里稍微介绍一下AISgen for D800K008,这个小软件是基于Windows环境的工具,它可以对DSP的各个时钟模块如PLL0、PLL1、SDRAM时钟、DDR时钟以及PSC模块进行配置,生成一段初始化代码,并嵌入到CCS生成的.out文件中,最终转换生成.AIS格式文件(这个文件可以认为是启动代码,BootLoader,也叫boot镜像,boot
image)。
(Using the TMS320C6748C6746C6742 Bootloader (Rev. F)P12)
AISgen问题
下面再看看仿真时,Gel文件对PLL初始化,EMIF模块时钟是多少。在创龙的Gel文件中,有以下代码段:
Set_Core_456MHz() {
device_PLL0(0,18,0,0,1,3,9);
GEL_TextOut(" PLL0 init
done for Core:456MHz, EMIFA:114MHz
","Output",1,1,1);
}
由代码中的提示可以猜出EMIFA的输入时钟应该是114MHz,再看device_PLL0函数,代码如下:
Set_Core_456MHz() {
device_PLL0(unsignedint
CLKMODE, unsignedint PLLM,
unsignedint POSTDIV,unsignedint
PLLDIV1, unsignedint PLLDIV2,
unsignedint PLLDIV3,
unsignedint PLLDIV7 ) {
unsignedint i=0;
/* Clear PLL lock bit */
CFGCHIP0
&=~(0x00000010);
/* Set PLLENSRC '0',bit 5, PLL Enable(PLLEN) selection is controlled through MMR */
PLL0_PLLCTL
&=~(0x00000020);
/* PLLCTL.EXTCLKSRC bit 9 should be left at 0 for Freon */
PLL0_PLLCTL
&=~(0x00000200);
/* Set PLLEN=0 to put in bypass mode*/
PLL0_PLLCTL
&=~(0x00000001);
/*wait for 4 cycles to allow PLLEN mux switches properly to bypass clock*/
for(i=0; i<PLLEN_MUX_SWITCH;
i++) {;}
/* Select the Clock Mode bit 8 as External Clock or On Chip Oscilator*/
PLL0_PLLCTL
&=0xFFFFFEFF;
PLL0_PLLCTL
|= (CLKMODE
<<8);
/*Clear PLLRST bit to reset the PLL */
PLL0_PLLCTL
&=~(0x00000008);
/* Disable the PLL output*/
PLL0_PLLCTL
|= (0x00000010);
/* PLL initialization sequence
Power up the PLL by setting PWRDN bit set to 0 */
PLL0_PLLCTL
&=~(0x00000002);
/* Enable the PLL output*/
PLL0_PLLCTL
&=~(0x00000010);
/*PLL stabilisation time- take out this step , not required here when PLL in bypassmode*/
for(i=0; i<PLL_STABILIZATION_TIME;
i++) {;}
/*Program the required multiplier value in PLLM*/
PLL0_PLLM
= PLLM;
/*If desired to scale all the SYSCLK frequencies of a given PLLC, program the POSTDIV ratio*/
PLL0_POSTDIV
=0x8000| POSTDIV;
/*Check for the GOSTAT bit in PLLSTAT to clear to 0 to indicate that no GO operation is currently in progress*/
while(PLL0_PLLSTAT
&0x1==1){}
/*Program the RATIO field in PLLDIVx with the desired divide factors. In addition, make sure in this step you leave the PLLDIVx.DxEN
bits set so clocks are still enabled (default).*/
PLL0_PLLDIV1
=0x8000| PLLDIV1;
// Fixed Ratio /1
PLL0_PLLDIV2
=0x8000| PLLDIV2;
// Fixed Ratio /2
PLL0_PLLDIV4
=0x8000| (((PLLDIV1+1)*4)-1);
// Fixed Ratio /4
PLL0_PLLDIV6
=0x8000| PLLDIV1;
// Fixed Ratio /1
PLL0_PLLDIV3
=0x8000| PLLDIV3;
// Variable Ratio (EMIF)
PLL0_PLLDIV7
=0x8000| PLLDIV7;
// Variable Ratio (RMII)
/*Set the GOSET bit in PLLCMD to 1 to initiate a new divider transition.*/
PLL0_PLLCMD
|=0x1;
/*Wait for the GOSTAT bit in PLLSTAT to clear to 0 (completion of phase alignment).*/
while(PLL0_PLLSTAT
&0x1==1) { }
/*Wait for PLL to reset properly.*/
for(i=0; i<PLL_RESET_TIME_CNT;
i++) {;}
/*Set the PLLRST bit in PLLCTL to 1 to bring the PLL out of reset*/
PLL0_PLLCTL
|=0x8;
/*Wait for PLL to lock.*/
for(i=0; i<PLL_LOCK_TIME_CNT;
i++) {;}
/*Set the PLLEN bit in PLLCTL to 1 to remove the PLL from bypass mode*/
PLL0_PLLCTL
|=0x1;
}(0,18,0,0,1,3,9);
GEL_TextOut(" PLL0 init
done for Core:456MHz, EMIFA:114MHz
","Output",1,1,1);
}
其中对PLL0各分频值设置如下:
/*Program the RATIO field in PLLDIVx with the desired divide factors. In addition, make sure in this step you leave the PLLDIVx.DxEN
bits set so clocks are still enabled (default).*/
PLL0_PLLDIV1
=0x8000| PLLDIV1;
// Fixed Ratio /1
PLL0_PLLDIV2
=0x8000| PLLDIV2;
// Fixed Ratio /2
PLL0_PLLDIV4
=0x8000| (((PLLDIV1+1)*4)-1);
// Fixed Ratio /4
PLL0_PLLDIV6
=0x8000| PLLDIV1;
// Fixed Ratio /1
PLL0_PLLDIV3
=0x8000| PLLDIV3;
// Variable Ratio (EMIF)
PLL0_PLLDIV7
=0x8000| PLLDIV7;
// Variable Ratio (RMII)
PLLDIV3为参数变量,传入的参数为3,可以看出PLL0_PLLDIV3被设置为3|0x8000,即PLL0的PLLDIV3寄存器的RATIO位被设为3,则PLL0_SYSCLK3分频值应为4,即PLL0_SYSCLK1/4(456MHz/4=114MHz),故EMIFA输入时钟应为114MHz。
(指南P145)
使用PLL0的OBSCLK时钟输出功能,输出时钟源选择PLL0_SYSCLK3,OSCDIV选择为0x19即25(则实际分频数为26,则输出的PLL0 OBSCLK时钟应等于PLL0_SYSCLK3/26),如果PLL0_SYSCLK3为114MHz,则输出的PLL0 OBSCLK应为4.4MHz左右(114MHz/26=4.4MHz)。使用示波器观察输出,可看到图中所示:
由图所示,输出的OBSCLK时钟频率的确是4.4MHz左右(见CH1,黄 {MOD}线),验证了EMIF的输入时钟PLL0_SYSCLK3的确是114MHz,而不是创龙代码所注释的91MHz。
(指南P148)
(指南P140)
(指南P130)