创龙TMS320C6748开发板———PLL模块和PINMUX说明

本文介绍了TMS320C6748 DSP中PLL(锁相环)模块的初始化配置过程,包括PLL0和PLL1模块的详细配置流程,并提供了一个简化配置的示例代码。此外,还介绍了如何使用TI PinMultiplex Utility软件进行管脚复用(PINMUX)模块的配置。
一、 下面我们介绍 PLL (锁相环)模块的初始化过程。
        一个系统最基础的模块就是时钟电路,而系统中各个模块的时钟又是不同的, TI 公司为 TMS320C6748 提供了 PLL0 PLL1 两个锁相环模块,为 DSP DDR uPP SPI I2C UART 等模块提供时钟。详细见下图:
        在写程序的时候经常用到这张表,查看相应模块对应的输出时钟,其中 PLL0_SYSCLK1 PLL0_SYSCLK2 PLL0_SYSCLK4 PLL0_SYSCLK6 这几个时钟输出分频系数不可调,也就是说他们的时钟只取决于 PLL1 PREDIV[ 预分频 ] PLLM[ 倍频 ] POSTDIV[ 后分频 ] 三个寄存器。
        下面我们通过 PLL 的结构图来具体说明 PLL0_SYSCLK1~7 PLL1_SYSCLK1~3 频率是如何配置的。
        1 PLL0 模块
        在创龙的核心板上搭载的是 24MHz 的晶体振荡器,这时我们需要配置 PLLCTL 寄存器中的 CLKMODE=0 来选择输入时钟;当然, 6748 也支持直接输入方波作为时钟,这时相应的配置 CLKMODE=1 即可。
        紧接着,我们开始配置 PREDIV PLLM POSTDIV 这三个寄存器来选择系统工作的最高频率,计算公式为:输出时钟频率 =OSCIN 24MHz )÷( PREDIV+1 )×( PLLM+1 )÷( POSTDIV+1 ),注意以上三个寄存器中有一位是使能位,需要使能才能更改频率。然后在 PLLCTL 寄存器中设置 PLLEN 位即可将时钟送入 7 个时钟模块,在经过相应的分频( PLLDIV1~7 )得到子系统时钟作为各个模块的输入时钟。至此配置完成。
        另外,在系统工作过程中如果我们需要更改系统频率该如何操作呢,显然,肯定不可以暂时关闭 PLL0 ,更改相应倍频、分频寄存器再打开。这时我们可以通过设置 PLLCTL 中的 EXTCLKSRC 位,将 PLL1_SYSCLK3 的时钟输入到 PLL0 7 个时钟模块前,同时清除 PLLCTL 中的 PLLEN 位,至此完成时钟切换为 PLL1 后就可以更改 PLL0 的倍频、分频比,配置完成后重新切换为 PLL0 即可。
        最后还需要说明的是在倍频器后有一路时钟 [ 不经过后分配 ] 直接经过 DIV4.5[4.5 倍分频 ] 作为 EMIFA 的时钟,也可以通过清除 CFGCHIP3 寄存器中的 EMA_CLKSRC 位配置 PLL0_SYSCLK3 作为 EMIFA 的时钟。
        2 PLL1 模块
       PLL1 模块与 PLL0 模块类似,不过没有了 PREDIV 寄存器, PLL1_SYSCLK1 时钟作为 DDR 模块的时钟输入。
        PLL1 模块中多了 PLLC1 OBSCLK 时钟,在 6748 上有 OBSCLK 这个引脚可以方便用户外接其他需要时钟的模块,时钟源可以通过 OCSEL 中的 OCSRC 位选择。
接下来我们给出各个子系统时钟支持的最高频率。
        3 PLL 模块的初始化配置过程
       a.  为了解锁 PLL 控制寄存器,在 KICK0R KICK1R 两个寄存器中分别写入 KICK0R:83E70B13h KICK1R:95A4F1E0h KICK0R KICK1R SYSCFG0 模块中。
       b.  如果配置 PLL0 模块,清除 CFGCHIP0 寄存器中的 PLL_MASTER_LOCK 位,如果配置 PLL1 模块,清除 CFGCHIP3 寄存器中的 PLL1_MASTER_LOCK 位。 CFGCHIP0 CFGCHIP3 SYSCFG0 模块中。
       c.  清除 PLLCTL 中的 PLLENSRC 位。
       d.  清除 PLLCTL 中的 EXTCLKSRC 位。
       e.  清除 PLLCTL 中的 PLLEN 位。
       f.  等待四个时钟周期。
       g.  清除 PLLCTL 中的 CLKMODE 位,选择晶体振荡器作为输入时钟。
       h.  清除 PLLCTL 中的 PLLRST 位,使 PLL0 复位。
       i.  设置 PLLCTL 中的 PLLDIS 位。 [PLLCTL 的第四位 ]
       j.  清除 PLLCTL 中的 PLLPWRDN 位。
       k.  清除 PLLCTL 中的 PLLDIS 位。
       l.  等待 2000 个时钟周期,使 PLL 工作稳定。 PLL_STABILIZATION_TIME
       m.  配置 PREDIV PLLM POSTDIV 三个寄存器。等待,直至 PLLSTAT 中的 GOSTAT 位为 0
       n.  配置 PLLDIV1~7
       o.  设置 PLLCMD 寄存器中的 GOSET 位。等待,直至 PLLSTAT 中的 GOSTAT 位为 0
       p.  等待 200 个周期。 PLL_RESET_TIME_CNT
       1.  设置 PLLCTL 中的 PLLRST 位,使 PLL0 退出复位状态。
       r.  等待 2400 个周期。 PLL_LOCK_CYCLES
       s.  设置 PLLCTL 中的 PLLEN 位。
       t.  如果配置 PLL0 模块,设置 CFGCHIP0 寄存器中的 PLL_MASTER_LOCK 位,如果配置 PLL1 模块,设置 CFGCHIP3 寄存器中的 PLL1_MASTER_LOCK 位。 CFGCHIP0 CFGCHIP3 SYSCFG0 模块中。
       u.  锁定 PLL 控制寄存器,在 KICK0R KICK1R 两个寄存器中分别写入 KICK0R:0hKICK1R: 0h KICK0R KICK1R SYSCFG0 模块中。
      
下面介绍个偷懒的方法,可以直接移植创龙电子给的 gel 文件中的部分代码:
#definePLLEN_MUX_SWITCH         4
#definePLL_LOCK_TIME_CNT        2400
#definePLL_STABILIZATION_TIME   2000
#definePLL_RESET_TIME_CNT       200
device_PLL0(unsignedint CLKMODE, unsigned int PLLM, unsigned int POSTDIV,unsigned int PLLDIV1,unsigned int PLLDIV2, unsigned int PLLDIV3, unsigned int PLLDIV7 ) {
    unsigned int i=0;
    /* Clear PLL lock bit */
    CFGCHIP0 &= ~(0x00000010);
    /* Set PLLENSRC '0',bit 5, PLLEnable(PLLEN) selection is controlled through MMR */
    PLL0_PLLCTL &= ~(0x00000020);
    /* PLLCTL.EXTCLKSRC bit 9 should be left at0 for Freon */
    PLL0_PLLCTL &= ~(0x00000200);
    /* Set PLLEN=0 to put in bypass mode*/
    PLL0_PLLCTL &= ~(0x00000001);
    /*wait for 4 cycles to allow PLLEN muxswitches properly to bypass clock*/
    for(i=0; i<PLLEN_MUX_SWITCH; i++) {;}
    /* Select the Clock Mode bit 8 as ExternalClock 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 setto 0 */
    PLL0_PLLCTL &= ~(0x00000002);
    /* Enable the PLL output*/
    PLL0_PLLCTL &= ~(0x00000010);
    /*PLL stabilisation time- take out thisstep , not required here when PLL in bypassmode*/
    for(i=0; i<PLL_STABILIZATION_TIME; i++){;}
    /*Program the required multiplier value inPLLM*/
    PLL0_PLLM   = PLLM;
    /*If desired to scale all the SYSCLKfrequencies of a given PLLC, program the POSTDIV ratio*/
    PLL0_POSTDIV = 0x8000 | POSTDIV;
    /*Check for the GOSTAT bit in PLLSTAT toclear to 0 to indicate that no GO operation is currently in progress*/
    while(PLL0_PLLSTAT & 0x1==1){}
    /*Program the RATIO field in PLLDIVx withthe desired divide factors. In addition, make sure in this step you leave thePLLDIVx.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 toinitiate a new divider transition.*/
    PLL0_PLLCMD |= 0x1;
    /*Wait for the GOSTAT bit in PLLSTAT toclear 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 tobring 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 toremove the PLL from bypass mode*/
    PLL0_PLLCTL |=  0x1;
}
二、下面我们介绍 PINMUX (管脚复用)模块的配置过程。
       6748 上有较多功能,有的引脚甚至有 5 个功能,通过配置 PINMUX0~19 完成引脚功能选择。这里我们使用 Ti 提供的 TI Pin Multiplex Utility 软件进行配置。如图所示:
        1 step3 中勾选需要用的模块。
        2 Details 中双击选择对应引脚需要用到的功能,一般完成( 1 )后此步骤只需勾选相应的 GPIO 即可。
设备树(device tree)机制是Linux内核从linux-3.x版本开始引进的一种机制,目的是解决内核源码的arch/arm目录下代码混乱的问题:随着ARM生态的快速发展,在内核源码的arch/arm目录下,存放着几十种arm芯片几百个开发板相关的源文件,很多开发板处理器的中断、寄存器等相关硬件资源都在这个目录下以.c或.h的文件格式定义。而对于内核来说,与这些硬件耦合,会导致内核代码混乱不堪,每个开发板上运行的内核镜像都必须单独编译配置,无法通用。什么时候Linux内核能像Windows镜像那样,无论你的电脑什么配置,一个Windows安装包,都可以直接下载安装运行呢?设备树机制,实现了Linux内核硬件平台的解耦:每个硬件平台的硬件资源使用一个设备树文件(xxx.dts)来描述,而不是在arch/arm下以.c 或 .h 文件来定义。Linux内核是一个通用的内核,在启动过程中,在通过解析设备树中的硬件资源来初始化某个具体的平台。 引入设备树后,很多内核驱动开发的工作也发生了变化:以往驱动工程师关注的头文件宏定义、寄存器定义,现在这些基本上不用关注,关注的重点则转向了如何根据硬件平台去配置修改设备树文件。很多驱动的编程接口也发生了变化,开始慢慢使用device tree提供的编程接口去开发驱动。本期课程主要面向嵌入式开发人员,分享Linux下驱动开发所需要的设备树知识必备技能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值