DSP

C6748_EMIF时钟配置

2019-07-13 17:35发布

创龙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)