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.

TMS320F28388D: 28388D crashes when switching PLL from XTAL to INTOSC2

Part Number: TMS320F28388D
Other Parts Discussed in Thread: C2000WARE

The problem arises when trying to reconfigure the PLL to run from INTOSC2, when it was running from XTAL before. Roughly 75% of the time, the MCU crashes in this situation, and often ends up at 0x3fd226.

I have attached a modified version of the TI "led_ex1_c28x_cm_blinky_cpu1" example that illustrates the problem.

First, the MCU is configured to run from XTAL, then INTOSC2.

If I disable either configuration step, the code runs fine. If I leave both enabled, the MCU will often crash. This code is compiled to run from RAM and I load it using CCS.

//#############################################################################
//
// FILE:   led_ex1_c28x_cm_blinky_cpu1.c
//
// TITLE:  LED Blinky Example
//
//! \addtogroup driver_cm_c28x_dual_example_list
//! <h1> LED Blinky Example</h1>
//!
//! This example demonstrates how to blink a LED using CPU1 and blink another
//! LED using CM (led_ex1_blinky_cm.c).
//!
//! \b External \b Connections \n
//!  - None.
//!
//! \b Watch \b Variables \n
//!  - None.
//!
//
//#############################################################################
// $TI Release: F2838x Support Library v2.00.00.03 $
// $Release Date: Sun Sep 29 07:45:41 CDT 2019 $
// $Copyright:
// Copyright (C) 2019 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.
// $
//#############################################################################

//
// Included Files
//
#include "driverlib.h"
//#include "device.h"

extern void Device_enableAllPeripherals(void);
extern void Device_initGPIO(void);

#define DEVICE_GPIO_PIN_LED1        31U  // GPIO number for LD2
#define DEVICE_GPIO_PIN_LED2        34U  // GPIO number for LD3
#define DEVICE_GPIO_CFG_LED1        GPIO_31_GPIO31  // "pinConfig" for LD2
#define DEVICE_GPIO_CFG_LED2        GPIO_34_GPIO34  // "pinConfig" for LD3

#define DEVICE_OSCSRC_FREQ_XTAL     20000000U
#define DEVICE_OSCSRC_FREQ_INTOSC   10000000U

#define DEVICE_SYSCLK_FREQ          190000000U
#define DEVICE_AUXCLK_FREQ          120000000U
#define DEVICE_LSPCLK_FREQ          (DEVICE_SYSCLK_FREQ/4)

#define DEVICE_DELAY_US(x) SysCtl_delay(((((long double)(x)) / (1000000.0L /  \
                              (long double)DEVICE_SYSCLK_FREQ)) - 9.0L) / 5.0L)


#define DEVICE_SETCLOCK_CFG_XTAL      (SYSCTL_OSCSRC_XTAL | SYSCTL_IMULT(38) | \
                                      SYSCTL_REFDIV(2) | SYSCTL_ODIV(2) | \
                                      SYSCTL_SYSDIV(1) | SYSCTL_PLL_ENABLE | \
                                      SYSCTL_DCC_BASE_1)

#define DEVICE_AUXSETCLOCK_CFG_XTAL   (SYSCTL_AUXPLL_OSCSRC_XTAL | SYSCTL_AUXPLL_IMULT(120) |  \
                                      SYSCTL_REFDIV(5U) | SYSCTL_ODIV(4U) | \
                                      SYSCTL_AUXPLL_DIV_1 | SYSCTL_AUXPLL_ENABLE | \
                                      SYSCTL_DCC_BASE_0)

#define DEVICE_SETCLOCK_CFG_INTOSC    (SYSCTL_OSCSRC_OSC2 | SYSCTL_IMULT(38) | \
                                      SYSCTL_REFDIV(2) | SYSCTL_ODIV(1) | \
                                      SYSCTL_SYSDIV(1) | SYSCTL_PLL_ENABLE | \
                                      SYSCTL_DCC_BASE_1)

#define DEVICE_AUXSETCLOCK_CFG_INTOSC (SYSCTL_AUXPLL_OSCSRC_OSC2 | SYSCTL_AUXPLL_IMULT(120) |  \
                                      SYSCTL_REFDIV(5U) | SYSCTL_ODIV(2U) | \
                                      SYSCTL_AUXPLL_DIV_1 | SYSCTL_AUXPLL_ENABLE | \
                                      SYSCTL_DCC_BASE_0)

//
// Main
//
void main(void)
{
    //
    // Disable the watchdog
    //
    SysCtl_disableWatchdog();

#ifdef _FLASH
    //
    // Copy time critical code and flash setup code to RAM. This includes the
    // following functions: InitFlash();
    //
    // The RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart symbols
    // are created by the linker. Refer to the device .cmd file.
    //
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);

    //
    // Call Flash Initialization to setup flash waitstates. This function must
    // reside in RAM.
    //
    Flash_initModule(FLASH0CTRL_BASE, FLASH0ECC_BASE, DEVICE_FLASH_WAITSTATES);
#endif
#ifdef CPU1

#if 1
    // Configure clock tree from XTAL
    SysCtl_setClock(DEVICE_SETCLOCK_CFG_XTAL);

    SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_4);

    SysCtl_setAuxClock(DEVICE_AUXSETCLOCK_CFG_XTAL);

    SysCtl_setCMClk(SYSCTL_CMCLKOUT_DIV_1,SYSCTL_SOURCE_AUXPLL);

    ASSERT(SysCtl_getClock(DEVICE_OSCSRC_FREQ_XTAL) == DEVICE_SYSCLK_FREQ);
    ASSERT(SysCtl_getLowSpeedClock(DEVICE_OSCSRC_FREQ_XTAL) == DEVICE_LSPCLK_FREQ);
    ASSERT(SysCtl_getAuxClock(DEVICE_OSCSRC_FREQ_XTAL) == DEVICE_AUXCLK_FREQ);
#endif

#if 1
    // Configure clock tree from INTOSC
    SysCtl_setClock(DEVICE_SETCLOCK_CFG_INTOSC);

    SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_4);

    SysCtl_setAuxClock(DEVICE_AUXSETCLOCK_CFG_INTOSC);

    SysCtl_setCMClk(SYSCTL_CMCLKOUT_DIV_1,SYSCTL_SOURCE_AUXPLL);

    ASSERT(SysCtl_getClock(DEVICE_OSCSRC_FREQ_INTOSC) == DEVICE_SYSCLK_FREQ);
    ASSERT(SysCtl_getLowSpeedClock(DEVICE_OSCSRC_FREQ_INTOSC) == DEVICE_LSPCLK_FREQ);
    ASSERT(SysCtl_getAuxClock(DEVICE_OSCSRC_FREQ_INTOSC) == DEVICE_AUXCLK_FREQ);
#endif

#endif

    //
    // Turn on all peripherals
    //
    Device_enableAllPeripherals();
    Device_initGPIO();

    //
    // Boot CM core
    //
//#ifdef _FLASH
//    Device_bootCM(BOOTMODE_BOOT_TO_FLASH_SECTOR0);
//#else
//    Device_bootCM(BOOTMODE_BOOT_TO_S0RAM);
//#endif

    //
    // Initialize GPIO and configure the GPIO pin as a push-pull output
    //
    Device_initGPIO();
    GPIO_setPadConfig(DEVICE_GPIO_PIN_LED1, GPIO_PIN_TYPE_STD);
    GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED1, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_LED2, GPIO_PIN_TYPE_STD);
    GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED2, GPIO_DIR_MODE_OUT);

    //
    // Configure CPU2 to control the LED GPIO
    //
    GPIO_setMasterCore(DEVICE_GPIO_PIN_LED2, GPIO_CORE_CM);

    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

    //
    // Loop Forever
    //
    for(;;)
    {
        //
        // Turn on LED
        //
        GPIO_writePin(DEVICE_GPIO_PIN_LED1, 0);

        //
        // Delay for a bit.
        //
        DEVICE_DELAY_US(500000);

        //
        // Turn off LED
        //
        GPIO_writePin(DEVICE_GPIO_PIN_LED1, 1);

        //
        // Delay for a bit.
        //
        DEVICE_DELAY_US(500000);
    }
}

//
// End of File
//

  • Hi Beat,

    Thanks for your post.  I'll get back to you on this issue after the holidays.

    Regards,

    Joseph

  • Hi,

    Please let us know if you are running this code on your custom board or TI board ?

    Regards,

    Vivek Singh

  • Hello Joseph and Vivek - this is with a TI controlCARD. Thanks!

  • Hi Beat,

    Noticed your configuration setting for INTOSC2 as follows:

    #define DEVICE_SETCLOCK_CFG_INTOSC (SYSCTL_OSCSRC_OSC2 | SYSCTL_IMULT(38) | \
    SYSCTL_REFDIV(2) | SYSCTL_ODIV(1) | \
    SYSCTL_SYSDIV(1) | SYSCTL_PLL_ENABLE | \
    SYSCTL_DCC_BASE_1)

    The reference divider is set to 2.  This means that INTOSC2 is prescaled by 2 before clocking the PLL, or 5MHz clock [f(INTCLK)] is being fed to PLL.  This is out of spec.  Please maintain f(INTCLK) to be within 10 to 25MHz as indicated in the device datasheet.  Try this following setup instead:

    #define DEVICE_SETCLOCK_CFG_INTOSC (SYSCTL_OSCSRC_OSC2 | SYSCTL_IMULT(38) | \
    SYSCTL_REFDIV(1) | SYSCTL_ODIV(2) | \
    SYSCTL_SYSDIV(1) | SYSCTL_PLL_ENABLE | \
    SYSCTL_DCC_BASE_1)

    Regards,

    Joseph

  • Hello Joseph,

    Thank you very much for the info. I had not noticed the f(INTCLK) constraint.

    Now per the data sheet, the same restriction applies to f(AUXINTCLK). Would you therefore agree that the following definition, taken from "device.h" in the latest C2000Ware (v2.01.00.00), does also violate this rule?

    #define DEVICE_AUXSETCLOCK_CFG       (SYSCTL_AUXPLL_OSCSRC_XTAL | SYSCTL_AUXPLL_IMULT(125) |  \
    		                                      SYSCTL_REFDIV(5U) | SYSCTL_ODIV(4U) | \
    		                                      SYSCTL_AUXPLL_DIV_1 | SYSCTL_AUXPLL_ENABLE | \
    		                                      SYSCTL_DCC_BASE_0)

    And, in "f2838x_sysctrl.c":

       InitAuxPll(XTAL_OSC, IMULT_125, REFDIV_5, ODIV_4, AUXPLLRAWCLK_BY_1, SYSCTL_DCC_BASE1);

    I have now adapted my test code as follows:

    #define DEVICE_SETCLOCK_CFG_XTAL      (SYSCTL_OSCSRC_XTAL | SYSCTL_IMULT(38) | \
                                          SYSCTL_REFDIV(2) | SYSCTL_ODIV(2) | \
                                          SYSCTL_SYSDIV(1) | SYSCTL_PLL_ENABLE | \
                                          SYSCTL_DCC_BASE_1)
    
    #define DEVICE_AUXSETCLOCK_CFG_XTAL   (SYSCTL_AUXPLL_OSCSRC_XTAL | SYSCTL_AUXPLL_IMULT(24) |  \
                                          SYSCTL_REFDIV(2) | SYSCTL_ODIV(2) | \
                                          SYSCTL_AUXPLL_DIV_1 | SYSCTL_AUXPLL_ENABLE | \
                                          SYSCTL_DCC_BASE_0)
    
    #define DEVICE_SETCLOCK_CFG_INTOSC    (SYSCTL_OSCSRC_OSC2 | SYSCTL_IMULT(38) | \
                                          SYSCTL_REFDIV(1) | SYSCTL_ODIV(2) | \
                                          SYSCTL_SYSDIV(1) | SYSCTL_PLL_ENABLE | \
                                          SYSCTL_DCC_BASE_1)
    
    #define DEVICE_AUXSETCLOCK_CFG_INTOSC (SYSCTL_AUXPLL_OSCSRC_OSC2 | SYSCTL_AUXPLL_IMULT(24) |  \
                                          SYSCTL_REFDIV(1) | SYSCTL_ODIV(2) | \
                                          SYSCTL_AUXPLL_DIV_1 | SYSCTL_AUXPLL_ENABLE | \
                                          SYSCTL_DCC_BASE_0)

    However, the MCU still crashes after a few consecutive loads from CCS.

    Note that if I compile the same program to run from FLASH, the MCU boots without a problem after POR or XRS resets. The issue seems somewhat related to the fact that no clean reset of the MCU is taking place between CCS loads.

    Can you recommend anything else I should be looking into?

    Thanks,

    Beat

  • Hi Beat,

    In you project under device folder, their is driverlib folder which is probably excluded from the build configuration. Can you include driverlib folder and re-build your project, and try to see if this issue still exists?

    Regards,

    Nirav

  • Nirav,

    I can confirm that the problem also occurs when using the driverlib source, including the most recent release (v2.01).

    Please note that you may have to load the program multiple times (>5 times) back to back before the crash occurs.

    What does it mean when the PC lands at 0x3FD226? Can I provide you with more information (register values after crash, etc)? Did you want to provide me with another controlCARD to see if this issue is specific to my board/chip?

    Thanks,

    Beat

  • Hi Beat,

    I was able to duplicate the issue on our end, and my observation is similar to what you are seeing at your end. While debugging we found an issue with the driverlib code which is causing the device to reset and jump back to the BOOT ROM starting address 0x3FD226 when doing the clock switch.

    Please add below lines of highlighted code before you configure PLL using INTOSC, this should resolve the issue you are seeing.

    #if 1

    EALLOW;
    HWREGH(CLKCFG_BASE + SYSCTL_O_CLKSRCCTL1) &= ~SYSCTL_CLKSRCCTL1_OSCCLKSRCSEL_M;
    EDIS;

    SysCtl_delay(12U);

    // Configure clock tree from INTOSC
    SysCtl_setClock(DEVICE_SETCLOCK_CFG_INTOSC);

    SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_4);

    SysCtl_setAuxClock(DEVICE_AUXSETCLOCK_CFG_INTOSC);

    SysCtl_setCMClk(SYSCTL_CMCLKOUT_DIV_1,SYSCTL_SOURCE_AUXPLL);

    ASSERT(SysCtl_getClock(DEVICE_OSCSRC_FREQ_INTOSC) == DEVICE_SYSCLK_FREQ);
    ASSERT(SysCtl_getLowSpeedClock(DEVICE_OSCSRC_FREQ_INTOSC) == DEVICE_LSPCLK_FREQ);
    ASSERT(SysCtl_getAuxClock(DEVICE_OSCSRC_FREQ_INTOSC) == DEVICE_AUXCLK_FREQ);
    #endif

    Regards,

    Nirav

  • Hi Nirav,

    Thank you very much for the rapid debugging of the issue. I will try the workaround as you suggested and will let you know should I run into any other issues.

    Also, can you please tell me what you think about my comment above regarding the Aux PLL configuration parameters in the TI examples? According to my understanding, the REFDIV value is violating the f(AUXINTCLK) requirement.

    Kind regards,

    Beat

  • Hi Beat,

    Yes, the initial values that you used in the attachment did violate the f(AUXINTCLK) requirements, but as per your later thread where you modified the settings based on Joseph's feedback below, they look fine. Below settings are good.

    #define DEVICE_AUXSETCLOCK_CFG_XTAL   (SYSCTL_AUXPLL_OSCSRC_XTAL | SYSCTL_AUXPLL_IMULT(24) |  \
                                          SYSCTL_REFDIV(2) | SYSCTL_ODIV(2) | \
                                          SYSCTL_AUXPLL_DIV_1 | SYSCTL_AUXPLL_ENABLE | \
                                          SYSCTL_DCC_BASE_0)
     
    #define DEVICE_AUXSETCLOCK_CFG_INTOSC (SYSCTL_AUXPLL_OSCSRC_OSC2 | SYSCTL_AUXPLL_IMULT(24) |  \
                                          SYSCTL_REFDIV(1) | SYSCTL_ODIV(2) | \
                                          SYSCTL_AUXPLL_DIV_1 | SYSCTL_AUXPLL_ENABLE | \
                                          SYSCTL_DCC_BASE_0)
    Regards,
    Nirav
  • As far as I can tell, this issue is now resolved. Thanks again.