This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PLL Divider issue TMS320C6457

Other Parts Discussed in Thread: OMAPL138

Hello,

We tried to configure SYSCLK6 divider value, we followed the steps given in the datasheet SPRUGL3.pdf, but we are not able  to change Divider value from default(i.e 10) to desired values(20, 30 etc)

We used Volatile pointer declaration and  KICK0 and KICK 1 register also but still value taken by SYSCLK6 divider is default(i.e 10) only.

Thanks

  • Hello Akshay,

    Have you ensured that you properly followed the initialization sequence for PLL mode ?

    Have you performed GO operation after setting the PLLDIV6 register ? You must apply the GO operation to change the PLL divider to new ratio.

    Regards,

    Senthil


     

  • Hi Akshay,

    Have you checked that you have written properly ?

    We used Volatile pointer declaration and  KICK0 and KICK 1 register also but still value taken by SYSCLK6 divider is default(i.e 10) only.

    Do step by step debug and confirm that value got reflected in CCS registers and could you please confirm that through JTAG.

    If possible share the code with us.

  • Hi,

    Attached below is the code.

    Code while((*pll_stat & 0x01) !=0 ); is getting stuck after GO command ( *pll_cmd |= 0x00000001;)

    When the above code while((*pll_stat & 0x01) !=0 ); is commented following is the result

    PLL Multipler is working but PLLDIV6 is not working as expected

    We need SYSCLK6 with lower frequency.
    The PLL function is not accepting PLLDIV6 = 20 or 30 etc.

    Thanks.

    Set_Pll1(20);        // This is called in our initilaisation function.

    // PLL 1 definitions (DSP clk and subsystems)
    #define PLL1_BASE           0x029A0000
    #define PLL1_PLLCTL         (PLL1_BASE + 0x100)   // PLL1 Control
    #define PLL1_PLLM           (PLL1_BASE + 0x110)   // PLL1 Multiplier
    #define PLL1_PREDIV         (PLL1_BASE + 0x114)   // PREDIV divider
    #define PLL1_POSTDIV        (PLL1_BASE + 0x128)   // POSTDIV divider
    #define PLL1_CMD            (PLL1_BASE + 0x138)   // CMD control
    #define PLL1_STAT           (PLL1_BASE + 0x13C)   // STAT control
    #define PLL1_DIV3           (PLL1_BASE + 0x120)   // DIV3 divider
    #define PLL1_DIV6           (PLL1_BASE + 0x168)   // DIV6 divider
    #define PLL1_DIV7           (PLL1_BASE + 0x16C)   // DIV7 divider
    #define PLL1_DIV8           (PLL1_BASE + 0x170)   // DIV8 divider

    void Set_Pll1( int pll_multiplier )
    {
        unsigned int* pll_ctl       = ( unsigned int* )PLL1_PLLCTL;
        unsigned int* pll_mult      = ( unsigned int* )PLL1_PLLM;
        unsigned int i;
        unsigned int rbmult;

        unsigned int div3=3, div6=10, div7=10, div8=10, prediv=1, postdiv=1;

        unsigned int* pll_div3      = ( unsigned int* )PLL1_DIV3;
        unsigned int* pll_div6      = ( unsigned int* )PLL1_DIV6;
        unsigned int* pll_div7      = ( unsigned int* )PLL1_DIV7;
        unsigned int* pll_div8      = ( unsigned int* )PLL1_DIV8;
        unsigned int* pll_cmd       = ( unsigned int* )PLL1_CMD;
        unsigned int* pll_stat      = ( unsigned int* )PLL1_STAT;
        unsigned int* pll_prediv    = ( unsigned int* )PLL1_PREDIV;
        unsigned int* pll_postdiv    = ( unsigned int* )PLL1_POSTDIV;

        int dsp_freq;

        rbmult = pll_multiplier;

        if (pll_multiplier>=8 && pll_multiplier<=32)
        {

            //  Step 1: Set PLL to BYPASS mode
            *pll_ctl &= 0xFFFFFFDF;             // Set PLL to Bypass mode
            *pll_ctl &= 0xFFFFFFFE;

            // Wait Bypass mode switch
            // Bypass sw time is 4 clkin cycles = (1/50000000) * 4 ~0.12 usec
            Wait_Soft(150);

            //  Step 2: Configure and stabilize PLL
            *pll_ctl |= 0x8;                    // Reset PLL

            // Verify if pll is in power down
            if ((*pll_ctl & 0x00000002) !=0 )
            {
                //*pll_ctl |= 0x00000010;         // Disable PLL
                *pll_ctl &= 0xFFFFFFFD;         // Power up PLL
                //*pll_ctl &= 0xFFFFFFEF;         // Enable PLL

                // Wait PLL Stabilization time
                // that is 150 usec
                // The following delay is much more than necessary and provide stable PLL...
                Wait_Soft(5000);
            }
            else
            {
                //*pll_ctl &= 0xFFFFFFEF;         // Enable PLL
            }

            // Step 3: Set PLL multiplier register (minus 1 desired mult value)
            *pll_mult = (pll_multiplier-1);       // Set PLL multipler
            *pll_prediv = (prediv-1) | 0x8000;    // Set PLL prediv divider
            *pll_postdiv = (postdiv-1) | 0x8000;    // Set PLL postdiv divider

            // Wait for GOSTAT to be cleared so no go operation is in progress

            Wait_Soft(25000);

          while((*pll_stat & 0x01) !=0 );   

            // Step 4. Set PLL dividers if needed
            *pll_div3 = (0x8000) | (div3 - 1);
            *pll_div6 = (0x8000) | (div6 - 1);
            *pll_div7 = (0x8000) | (div7 - 1);
            *pll_div8 = (0x8000) | (div8 - 1);

            // Gives the GO cmd
            *pll_cmd |= 0x00000001;

            // Wait for phase alignment
            Wait_Soft(25000);

     //       while( (*pll_stat & 0x01) !=0 );  getting stuck

            // Step 5: Wait for PLL to lock

            *pll_ctl &= 0xFFFFFFF7;             // Release PLL from Reset

            *pll_ctl |= 0x00000001;             // Set PLL to PLL mode

        }
        else
        {
         //     printf( "PLL1 Setup... Unsuccessful.\n" );
          ///        printf( "PLL1 Setup... ERROR: multiplier is outside allowed range!\n",,2,,);
        }
        *pGPIOOutReg =*pGPIOOutReg | 0x00004000;
    }

  • Hi,

    Does PSC controller have any impact on the PLLDIV6 settings done in Set_Pll1()  function.

    Is there any sequence to configure the PSC registers.

    Thanks.

  • Hi Akshay,

    Sorry for the delayed response.

    I don't have a C6457 board with me so I have tried it on my OMAPL138 LCDK board (C6748 DSP ).

    Also I'm not seeing much difference between them.

    I'm able to modify the PLLDIV6 (PLL0_SYSCLK6) frequency using the following code snippet.

    Why did you re-init the PLL controller like bypass, power down and divider etc.,

    If you want to change the particular DIVIDER then you can change the divider alone.

    I have implemented the code in TI OMAPL138 LCDK ARM GPIO example.

    Please note that you have to write (set or clear) particular bit when you are writing "PLLCMD" register for go operation.

    Ex:

        *pllc0_cmd |= (1 << 0);

        *pll_cmd |= 0x00000001;

    /**
     * \file    gpioCardDetect.c
     *
     * \brief   This is a sample application file demonstrating the use of
     *          a GPIO pin to generate an interrupt whenever an MMC/SD card
     *          is inserted or ejected from the Evaluation Module(EVM).
     */
    
    /*
    * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 
    *
    *  Redistribution and use in source and binary forms, with or without 
    *  modification, are permitted provided that the following conditions 
    *  are met:
    *
    *    Redistributions of source code must retain the above copyright 
    *    notice, this list of conditions and the following disclaimer.
    *
    *    Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in the 
    *    documentation and/or other materials provided with the   
    *    distribution.
    *
    *    Neither the name of Texas Instruments Incorporated nor the names of
    *    its contributors may be used to endorse or promote products derived
    *    from this software without specific prior written permission.
    *
    *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */
    
    #include "gpio.h"
    #include "psc.h"
    #include <stdio.h>
    
    #include "soc_OMAPL138.h"
    #include "lcdkOMAPL138.h"
    
    #include "lcdkOMAPL138.h"
    #include "soc_OMAPL138.h"
    #include "hw_syscfg0_OMAPL138.h"
    
    void Set_Pll1(int pll_multiplier);
    
    void Set_Pllc0(int pll_divider);
    
    #define PLLC0_BASE           0x01C11000
    #define PLLC0_PLLCTL         (PLLC0_BASE + 0x100)   // PLL1 Control
    #define PLLC0_PLLM           (PLLC0_BASE + 0x110)   // PLL1 Multiplier
    #define PLLC0_PREDIV         (PLLC0_BASE + 0x114)   // PREDIV divider
    #define PLLC0_POSTDIV        (PLLC0_BASE + 0x128)   // POSTDIV divider
    #define PLLC0_CMD            (PLLC0_BASE + 0x138)   // CMD control
    #define PLLC0_STAT           (PLLC0_BASE + 0x13C)   // STAT control
    #define PLLC0_DIV4           (PLLC0_BASE + 0x160)   // DIV4 divider
    #define PLLC0_DIV5           (PLLC0_BASE + 0x164)   // DIV5 divider
    #define PLLC0_DIV6           (PLLC0_BASE + 0x168)   // DIV6 divider
    #define PLLC0_DIV7           (PLLC0_BASE + 0x16C)   // DIV7 divider
    
    unsigned int* pllc0_ctl       = ( unsigned int* )PLLC0_PLLCTL;
    unsigned int* pllc0_mult      = ( unsigned int* )PLLC0_PLLM;
    //unsigned int i;
    //unsigned int rbmult;
    
    unsigned int div4=4, div5=5, div6=6, div7=7;
    //prediv=1, postdiv=1;
    
    unsigned int* pllc0_div4      = ( unsigned int* )PLLC0_DIV4;
    unsigned int* pllc0_div5      = ( unsigned int* )PLLC0_DIV5;
    unsigned int* pllc0_div6      = ( unsigned int* )PLLC0_DIV6;
    unsigned int* pllc0_div7      = ( unsigned int* )PLLC0_DIV7;
    unsigned int* pllc0_cmd       = ( unsigned int* )PLLC0_CMD;
    unsigned int* pllc0_stat      = ( unsigned int* )PLLC0_STAT;
    unsigned int* pllc0_prediv    = ( unsigned int* )PLLC0_PREDIV;
    unsigned int* pllc0_postdiv    = ( unsigned int* )PLLC0_POSTDIV;
    
    #define PLLC0_OBSCLK          0x01C11104   // OBSCLK
    
    unsigned int* pllc0_obsclk      = ( unsigned int* )PLLC0_OBSCLK;
    
    #define PLLC0_OSCDIV		0x01C11124
    
    unsigned int* pllc0_oscdiv      = ( unsigned int* )PLLC0_OSCDIV;
    
    
    
    //void CLKOUTPinMux13Setup(void);
    
    
    /****************************************************************************/
    /*              LOCAL FUNCTION PROTOTYPES                                   */
    /****************************************************************************/
    static void Delay(volatile unsigned int delay);
    
    /****************************************************************************/
    /*              GLOBAL VARIABLES                                            */
    /****************************************************************************/
    
    /****************************************************************************/
    /*             LOCAL FUNCTION DEFINITIONS                                   */
    /****************************************************************************/
    
    
    
    int main(void)
    {
    
    	CLKOUTPinMux13Setup();
    
    	*pllc0_obsclk = 0x1c;
    
        printf( "PLLC0 OBSCLK = %p %p\n",*pllc0_obsclk,pllc0_obsclk);
    
        *pllc0_oscdiv = 0x8002;
    
        printf( "PLLC0 OBSCLK = %p %p pllc0_oscdiv %p\n",*pllc0_obsclk,pllc0_obsclk,*pllc0_oscdiv);
    
    
    	Set_Pllc0(4);        // This is called in our initilaisation function.
    
    
    
        /* The Local PSC number for GPIO is 3. GPIO belongs to PSC1 module.*/
        PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_GPIO, PSC_POWERDOMAIN_ALWAYS_ON,
    		     PSC_MDCTL_NEXT_ENABLE);
    
        /* Pin Multiplexing of pin 12 of GPIO Bank 6.*/
        GPIOBank6Pin12PinMuxSetup();
    
        /* Sets the pin 109 (GP6[12]) as input.*/
        GPIODirModeSet(SOC_GPIO_0_REGS, 109, GPIO_DIR_OUTPUT);
    
        while(1)
        {
    		GPIOPinWrite(SOC_GPIO_0_REGS, 109, GPIO_PIN_LOW);
    
    		Delay(1000000);
    
    		GPIOPinWrite(SOC_GPIO_0_REGS, 109, GPIO_PIN_HIGH);
    
    		Delay(1000000);
        }
    
    
    }
    
    #if 0
    void CLKOUTPinMux13Setup(void)
    {
         unsigned int savePinmux = 0;
    
         /*
         ** Clearing the bit in context and retaining the other bit values
         ** in PINMUX13 register.
         */
         savePinmux = (HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(13)) & ~(SYSCFG_PINMUX13_PINMUX13_7_4));
    
         /* Setting the pins corresponding to CLKOUT in PINMUX13 register.*/
         HWREG(SOC_SYSCFG_0_REGS + SYSCFG0_PINMUX(13)) =
              (PINMUX13_CLKOUT_7_4_ENABLE | savePinmux);
    
    }
    
    #endif
    
    
    void Set_Pllc0(int pll_divider)
    {
    
    	//Clear go bit
        *pllc0_cmd &= ~(1 << 0);
    
        Delay(5000);
    
        while( (*pllc0_stat & 0x01) !=0 ); 
        //*pllc0_div6 = 0x8006;
        *pllc0_div6 = (0x8000) | (pll_divider - 1);
    
        Delay(5000);
    
    
       //Set go bit
        *pllc0_cmd |= (1 << 0);
    
        Delay(5000);
    
        while( (*pllc0_stat & 0x01) !=0 ); 
    
    
    }
    
    /*
    ** \brief  This function checks the insertion status of the MMC/SD card
    **         in the device and prints related statements on the serial
    **         commuincation console of the external device.
    **         
    */
    
    /*
    ** \brief   This function can be called to generate a delay.
    */
    
    static void Delay(volatile unsigned int delay)
    {
        while(delay--);
    }