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.

Oddness setting up MOSC on Tiva 129X with external 25MHz osc.

I'm working on an old problem that happens on my Tivas that are in high volume production - They fail to start up about 1 time in a thousand.  For my application, thats a crazy high fail rate.  Luckily we can recover.     I've been running local regressions, and I've seen the failure to self reset problem -  

Amit's patch (which I already got from the FAE) cleared up the failure to restart issue, and now I've uncovered a separate issue - my parts eventually hang when switching from MOSC to PLL.     My parts start out in PIOSC, and then I switch to MOSC and do setup and startup work before spinning up the PLL.

This all started because the PIOSC doesn't meet spec.   I need a reliable UART so that I can report issues when my boards get tested at manufacturing time prior to shipment to their final customer.   I don't want to reject boards because PIOSC is far enough out to screw up the UART self test report.  

My part is running off of an external 25Mhz oscillator.   Here's how I set it up:

	int sysclock = SysCtlClockFreqSet( (SYSCTL_XTAL_25MHZ|SYSCTL_OSC_MAIN), SYSFREQ_XTAL);
	
	if ( sysclock == 0 ) {
		UARTprintf("Clock Fail ");
		// DumpOSC();
		UARTSpinFlush();		
	}
	
	ROM_UARTDisable(UART1_BASE);
	ROM_UARTClockSourceSet(UART1_BASE,UART_CLOCK_SYSTEM);
 	UARTStdioConfig(1, 115200, sysclock);

	UARTprintf("MOSC(%d) ", sysclock);

The part that baffles me is that my system somehow doesn't run at 25Mhz.    SysctlClockFreqSet() returns  22857142.

If I use that value to config my UART, I get output.  If I go with 25M, I get UART garbage.    Sadly, the UART is on PQ4, so I can't use clock-out.

So a few questions - 

1 - Whats going on here with SysCtlFreqSet?   Is it really somehow running my system at 22MHz?

2 -  The code (SysCtlClockFreqSet()  refers to the OSCRNG bit as being related to drive strength, but the data sheet makes no mention of this.  If its truly a drive strength setting should I be using it with a SE clock source?

        //
        // Increase the drive strength for MOSC of 10 MHz and above.
        //
        if(i32XtalIdx >= (SysCtlXtalCfgToIndex(SYSCTL_XTAL_10MHZ) -
                          (SysCtlXtalCfgToIndex(SYSCTL_XTAL_5MHZ))))
        {
            ui32MOSCCTL |= SYSCTL_MOSCCTL_OSCRNG;
        }

3 -  SysCtlFreqSet() contains this stanza -

    if((ui32Config & SYSCTL_USE_OSC) == SYSCTL_USE_PLL)
    {
        <snipped>
    }
    else
    {
        //
        // Set the Flash and EEPROM timing values for PIOSC
        //
        HWREG(SYSCTL_MEMTIM0) = _SysCtlMemTimingGet(16000000);

Which suggests to me that I'm running my system at 25MHz using memory timing values for 16Mhz.   The table in the data sheet indicates that I'll need different MEMTIM0 values.   Could that be the source of my part hangs?

  • Hello R Sexton

    Is this configuration failing in the first iteration or does it fail intermittently?

    Also note that the Errata #22 and #23 effectively make the use of MOSC as the system clock not a valid combination. You must lock the PLL

    Regards
    Amit
  • MOSC appears to be working, just not as expected. The intermittent fails happen when switching from MOSC to the PLL at startup time.

    I'll update the code to go directly from PIOSC to the PLL and see if that makes a difference.
  • Hello R Sexton,

    Is the device being forced into startup by a system/software reset?

    Regards
    Amit
  • I'm triggering a reset via the NVIC.      The full cycle is:

    1 Bootloader uses, but doesn't initialize  PIOSC ( It switches to  PLL for network updates, but I'm not doing that)

    2 Main App explicitly selects PIOSC (SysCtlClockFreqSet(SYSCTL_OSC_INT, SYSFREQ_PIOSC))  and generates startup messages via UART - Its possible that the PLL is running, so I choose a known state.

    3 Main App starts PLL and starts up the network stack.

    4 Regression script requests a reset via a UART command, and the resultant system call triggers reset via the NVIC.   Return to step one.

    I typically get a fail within a thousand cycles.  I added code to re-try a failed PLL lock, but I've never seen it trigger.

    On thing I can't figure out from the data sheet or the libraries is what MOSC config I should use with my 25MHz single-ended input clock.

    This little register write is common in all of the ethernet startup examples:

    HWREG(SYSCTL_MOSCCTL) = SYSCTL_MOSC_HIGHFREQ;

    But I don't know if it's specific to crystal operation or not.    sysctl.c suggests that it is for use with crystals.

  • Hello R Sexton,

    1. PIOSC is always running when the device is in Active State
    2. The Main APP calling the SysCtlClockFreqSet is not required as it is the default state after the Reset

    When the hang occurs, I would suggest connecting the debugger and checking RSCLKCFG, MEMTIM0, PLLFREQ0, PLLFREQ1 and PLLSTAT registers in System Control. Also to check is the value of the CPU's SP and PC register

    Regards
    Amit
  • I captured one last night.   The system went into hardfault someplace in between the bootloader and the main app.    

    The addresses don't make sense.   I'm showing code addresses in the boot loader, but a stack pointer that applies to the main application.

    Registers - after the boot loader executes, but prior to PLL startup - 

    PLL Regs:

    CPU0 > md 0x400fe160 0x10

    400fe160:  00800014 00000000  00000001 00000000   ................

    Memtim0:

    CPU0 > md 0x400fe0c0 0x10

    400fe0c0:  00300030 00000000  00000000 00000000   0.0.............

    RSCLKCONFIG:

    CPU0 > md 0x400fe0b0 0x10

    400fe0b0:  30000013 00000000  00000000 00000000   ...0............

  • Hello Robert,

    The register value shows that the PLL is being used with a System Clock of 12.5 MHz and being sourced from the PIOSC.

    So some part of the code is still causing the PLL to be invoked and it is doing without the patch...

    Regards
    Amit
  • The guilty code was SysCtlClockFreqSet().    I called it this way:

    return(SysCtlClockFreqSet(SYSCTL_OSC_INT, 16000000));

    I've since purged that code as part of simplifying all of this.     I don't touch the clocks at all until I switch from PIOSC to PLL.    I'm still seeing the hangs after a few hundred to few thousand cycles.  They happen somewhere during boot loader operation, prior to the initial UART banner.   The part is in hard fault and the register dumps don't really make sense.  

    Here's the register results from the updates in sysctl.c code, after I call SysCtlClockFreqSet();

    PLLREGS=800060,4,1 MEMTIM0=1950195 RSCLKCONFIG=33300003

  • Hello Robert,

    I believe the offending code is setting RSCLKCONFIG=33300003 (The Errata#22 asks for the OSCSRC to be PIOSC and not MOSC)

    If you are using the boot loader code from TivaWare, then it should be in bl_usb.c or bl_main.c

    Regards
    Amit
  • OSCSRC is actually being set by SysCtlClockFreqSet(). Looking at the code, its not clear where.

    I spotted this:

    //
    // Set the PLL source select to MOSC.
    //
    ui32OscSelect = SYSCTL_RSCLKCFG_OSCSRC_MOSC;
    ui32OscSelect |= SYSCTL_RSCLKCFG_PLLSRC_MOSC;

    But that doesn't seem to be the problem.

    I'm manually switching it back over after calling the PLL setup code ( RSCLKCONFIG=33000003) and I'm running tests now.
  • Hello Robert

    The Errata actually sets the RSCLKCFG.OSCSRC back to PIOSC. Can you please send (attach to the forum post) your copy of sysctl.c, to see if all changes have been incorporated?

    Regards
    Amit
  • 0451.sysctl.cHere's my local copy of sysctl.c

  • It appears that setting RSCLKCFG.OSCSRC back to PIOSC after SysCtlClockFreqSet() gets me a reliable reboot, but I'm still seeing system failure during PLL startup.
  • Hello Robert,

    There is one more change to make (which the errata document missed out during an edit). Replace the lines 2284-2299 of your local copy of sysctl.c with the following lines

    if((HWREG(SYSCTL_PLLFREQ1) !=
    (g_pppui32XTALtoVCO[i32VCOIdx][i32XtalIdx][1] |
    g_pppui32XTALtoVCO[i32VCOIdx][i32XtalIdx][2])) ||
    (HWREG(SYSCTL_PLLFREQ0) !=
    (g_pppui32XTALtoVCO[i32VCOIdx][i32XtalIdx][0] |
    SYSCTL_PLLFREQ0_PLLPWR)))
    {
    bNewPLL = true;
    }
    else
    {
    bNewPLL = false;
    }


    Regards
    amit
  • Got it.   I'm running tests now.   Updated file attached.

    4010.sysctl.c

  • No luck. I've gone from failures (hangs at PLL lock) after 1k-5k worth of cycles to fails after 10k cycles.

    sysctl.c is leaving RSCLKCFG in the wrong state after PLL config: RSCLKCONFIG=33300003

    I'm working around this with HWREG(SYSCTL_RSCLKCFG) &= ~SYSCTL_RSCLKCFG_OSCSRC_M; Right after SysCtlClockFreqSet().

  • Hello Robert,

    When the workaround code is executed and a step over done via IDE, then does the OSCSRC show up as 0x0.

    If yes, then somewhere in the code the bits are being set back to 0x3...

    Regards
    Amit
  • Its definitely happening in sysctl.c. I'm dumping the register before and after it runs. I can't figure out where. I'll break out a debugger and step through the code. I don't use an IDE.
  • Hello Robert

    Then the sysctl.c needs to have the last line as per what you have done in the code for RSCLKCFG. if not then perhaps a second call is present in the code which does cause the register to revert

    Regards
    Amit
  • I think I've got it. Its was a build issue - I was running the old code for the main app, and the new code in the boot loader.

    I found that out when I tried to instrument the new sysctl.c.

    This looks wrong, and still in still in your sysctl.c:


    //
    // Set the PLL source select to MOSC.
    //
    ui32OscSelect = SYSCTL_RSCLKCFG_OSCSRC_MOSC;
    ui32OscSelect |= SYSCTL_RSCLKCFG_PLLSRC_MOSC;

    I believe that should be:

    //
    // Set the PLL source select to MOSC.
    //
    ui32OscSelect = SYSCTL_RSCLKCFG_OSCSRC_PIOSC;
    ui32OscSelect |= SYSCTL_RSCLKCFG_PLLSRC_MOSC;


    I'm running tests again now. I should have results tomorrow. Hopefully it'll make it all night.
  • Hello Robert,

    The updated errata Appendix shows that the correction is made at the exit of the API.

    I assumed that the rest of the API in the sysctl.c attached in an earlier post did take that into account. Note that the TivaWare 2.1.3 is the one which would have the fix. So TivaWare 2.1.2 or earlier will still have the old code.

    Regards
    Amit
  • I think I'm there.   I have two 129x-based based designs that have made it past 20k cycles with the latest sysctl.c from Amit.   Thats a record.  

    I'm running with the minor change listed earlier in the thread so that MOSC is never enabled, not even temporarily.

  • Hello Robert,

    That is encouraging news. Let us run the design to 1M+ to be very very confident. Our last test report on the issue was 9M+.

    Regards
    Amit
  • I ran two different designs over the holiday weekend, and they made it to 50k and 100k successful cycles respectively.    I've got another design running now that will run for a few days.

    I am making arrangements to run the updated code on boards in our application environment - things are a little different there.   When it works there I'll consider this closed.

    Thanks for all the help.

  • Hello Robert

    Sure. But do update the thread. Also do note that the updated Errata is also released with the fix in the Appendix 3 for missing statement

    Regards
    Amit
  • The PLL changes are looking good. I've got a test unit thats been cycling for more than a week.

    I've just learned that they also break USB host, so it's time for a another round of debug. I suspect that the USBCC register is no longer correct, but I'll have to get NDA'd to be sure.
  • Aha.   The the PLL changes that fix this startup issue involve running the PLL at 240MHz instead of 480.

    The existing USB code uses a 8:1 divider to get the required 60MHz USB Phy clock.    I changed the divisor on USBCC and its working again.     The raw PLL also goes to the ADC and the Ethernet MAC.     I'll have to adjust the ADC divisor as well. 

  • Hello Robert

    Yes, that needs to be updated. The VCO is now divided thus affecting the peripheral dividers.

    Regards
    Amit