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.

SysCtlMOSCConfigSet and SYSCTL_MOSC_VALIDATE

Other Parts Discussed in Thread: TM4C123BE6PZ

I am using CCS 5.4, Tivaware 2.0 and a TM4C1`23BE6PZ.  I would like to use SysCtlMOSCConfigSet and SYSCTL_MOSC_VALIDATE to avoid trying to use an non-existent XTAL in SysCtlClockSet.

The code is:

SysCtlMOSCConfigSet(SYSCTL_MOSC_VALIDATE);
SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_20MHZ);

I step past the first function call, but when I step past the second call I end up in the FaultISR.  It has the same feel as addressing a peripheral that has not been enabled.  But there is no SYSTCTL_PERIPH_MOSC_VALIDATE peripheral.
When I comment out the first call, the program executes as expected.

I find this call documented in the Tivaware user guide, but only one example of the call in the examples using a different argument. 

On another target I use the SYSCTL_MOSC_NO_XTAL arg with no issue.

Using the ROM_ version of the call does not help.

Is there an example of calling the MOSC validation functionality?

Is there something else I need to be doing to get this to work?

I replace the function call with:

HWREG(SYSCTL_MOSCCTL_R) = SYSCTL_MOSC_VALIDATE;

And my program runs as expected. 

While in emulation, I do not see the register's value change using either method.

  • Hi John,

    The MOSC Validate is used to enable the clock monitor circuit. It is documented in the data sheet as well, that if the MOSC Validate bit is set and the MOSCIM in not set then on a clock failure it will generate an internal reset and set the SYSCTL.RESC.MOSCFAIL bit. Did you check the same?

    When you replace it with the HWREG then you are not using the define correctly. HWREG is (*((volatile uint32_t *)(x))) and SYSCTL_MOSCCTL_R is (*((volatile uint32_t *)0x400FE07C)). So you may be writting to a flash or sram location where it will have no affect or accept the write. You have to use HWREG(SYSCTL_MOSCCTL)

    Regards

    Amit

  • Very sorry, I missed the response in my email.  I will try your suggestion in the next few days.

  • I am looking at the TM4C123BE6PZ manual.  In one place it seems like setting MOSCCTL.MOSCIM will not generate an interrupt, but just set a bit, and in another it indicates a interrupt will be generated, but it does not specify which interrupt vector.

    Which is it supposed to be?

    Under the description of MOSCCTL I see:


    MOSC Failure Action
    Value  Description
    1 If the MOSC fails, an interrupt is generated as indicated by the
     MOFRIS bit in the RIS register..

    0 If the MOSC fails, a MOSC failure reset is generated and reboots
     to the NMI handler.


    In section 5.2.5.8 Main Oscillatyor Verification Circuit I see just a bit set.

    if the MOSCIM bit in the MOSCCTL register is set, then the following sequence is performed by the
    hardware:
    1. The system clock is switched from the main oscillator to the PIOSC.
    2. The MOFRIS bit in the RIS register is set to indicate a MOSC failure.

  • Hello John,

    If the MOSCCTL.MOSCIM bit is set then the interrupt will be generated on a MOSC failure if the IMC.MOFIM bit is set. If the IMC.MOFCIM bit is not set then RIS will still be logged

    Regards

    Amit

  • Experimentally, the code steps on, the MOSC not working, but PIOSC looks like it is clocking.  I.E, no interrupt is generated.

  • Hello John,

    Can you send across the Register Dump for the registers in question?

    Also have you enabled the Interrupt for System Control Module and assigned it an ISR?

    Regards

    Amit

  • Amit Ashara said:

    Can you send across the Register Dump for the registers in question?

    Yes

    Amit Ashara said:

    Also have you enabled the Interrupt for System Control Module and assigned it an ISR?

    No

    I have moved onto the following code...

        // Set us up to switch to PIOSC on MOSC failure and set MIFRIS in RIS register
        // See Main Oscillator Verification Circuit section in chip spec.
        HWREG(SYSCTL_MISC) |= 0x0000008;
        HWREG(SYSCTL_MOSCCTL) = SYSCTL_MOSC_VALIDATE | SYSCTL_MOSC_INTERRUPT;
    
        // ... much code
    
        if (HWREG(SYSCTL_RIS) & 0x00000008 ) {
            SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_INT);
            MOSC_Failed = TRUE;
            // Clear RIS.MOFRIS and MISC.MOFMIS, by setting MISC.MOFMIS
            HWREG(SYSCTL_MISC) |= 0x0000008;
        }
        else {
            SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                               SYSCTL_XTAL_20MHZ);
        }
    
        // ... much code
    
       if (MOSC_Failed) {
            TCAN_TraceC8("MOSCfail");
        }
        else {
            TCAN_TraceC8("MOSCpass");
        }

    But this leaves me frustrated as well.  With a working MOSC, I run and get 'MOSCpass' every time in emulation.  I quite emulation and do not touch a thing, except to power cycle.  I get 'MOSCfail' every time.

    521177 14
    R SYSCTL_SYSCTL_DID0 0x0000000B 0x18050101
    R SYSCTL_SYSCTL_DID1 0x0000000B 0x10C3442C
    R SYSCTL_SYSCTL_DC0 0x0000000B 0x007F003F
    R SYSCTL_SYSCTL_DC1 0x0000000B 0x13332FFF
    R SYSCTL_SYSCTL_DC2 0x0000000B 0x070FF337
    R SYSCTL_SYSCTL_DC3 0x0000000B 0xBFFFFFFF
    R SYSCTL_SYSCTL_DC4 0x0000000B 0x0004F1FF
    R SYSCTL_SYSCTL_DC5 0x0000000B 0x0F3000FF
    R SYSCTL_SYSCTL_DC6 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DC7 0x0000000B 0xFFFFFFFF
    R SYSCTL_SYSCTL_DC8 0x0000000B 0xFFFFFFFF
    R SYSCTL_SYSCTL_PBORCTL 0x0000000B 0x00007FFF
    R SYSCTL_SYSCTL_SRCR0 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRCR1 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRCR2 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_RIS 0x0000000B 0x00000140
    R SYSCTL_SYSCTL_IMC 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_MISC 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_RESC 0x0000000B 0x00000002
    R SYSCTL_SYSCTL_RCC 0x0000000B 0x01581600
    R SYSCTL_SYSCTL_GPIOHBCTL 0x0000000B 0x00007E00
    R SYSCTL_SYSCTL_RCC2 0x0000000B 0xC1004000
    R SYSCTL_SYSCTL_MOSCCTL 0x0000000B 0x00000003
    R SYSCTL_SYSCTL_RCGC0 0x0000000B 0x00000040
    R SYSCTL_SYSCTL_RCGC1 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_RCGC2 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGC0 0x0000000B 0x00000040
    R SYSCTL_SYSCTL_SCGC1 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGC2 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGC0 0x0000000B 0x00000040
    R SYSCTL_SYSCTL_DCGC1 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGC2 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DSLPCLKCFG 0x0000000B 0x07800000
    R SYSCTL_SYSCTL_SYSPROP 0x0000000B 0x00001D31
    R SYSCTL_SYSCTL_PIOSCCAL 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_PIOSCSTAT 0x0000000B 0x002F002F
    R SYSCTL_SYSCTL_PLLFREQ0 0x0000000B 0x00000050
    R SYSCTL_SYSCTL_PLLFREQ1 0x0000000B 0x00000003
    R SYSCTL_SYSCTL_PLLSTAT 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_DC9 0x0000000B 0x00FF00FF
    R SYSCTL_SYSCTL_NVMSTAT 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_PPWD 0x0000000B 0x00000003
    R SYSCTL_SYSCTL_PPTIMER 0x0000000B 0x0000003F
    R SYSCTL_SYSCTL_PPGPIO 0x0000000B 0x000003FF
    R SYSCTL_SYSCTL_PPDMA 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_PPHIB 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_PPUART 0x0000000B 0x000000FF
    R SYSCTL_SYSCTL_PPSSI 0x0000000B 0x0000000F
    R SYSCTL_SYSCTL_PPI2C 0x0000000B 0x0000003F
    R SYSCTL_SYSCTL_PPUSB 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_PPCAN 0x0000000B 0x00000003
    R SYSCTL_SYSCTL_PPADC 0x0000000B 0x00000003
    R SYSCTL_SYSCTL_PPACMP 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_PPPWM 0x0000000B 0x00000003
    R SYSCTL_SYSCTL_PPQEI 0x0000000B 0x00000003
    R SYSCTL_SYSCTL_PPEEPROM 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_PPWTIMER 0x0000000B 0x0000003F
    R SYSCTL_SYSCTL_SRWD 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRTIMER 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRGPIO 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRDMA 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRHIB 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRUART 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRSSI 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRI2C 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRCAN 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRADC 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRACMP 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRPWM 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRQEI 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SREEPROM 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SRWTIMER 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_RCGCWD 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_RCGCTIMER 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_RCGCGPIO 0x0000000B 0x000003FF
    R SYSCTL_SYSCTL_RCGCDMA 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_RCGCHIB 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_RCGCUART 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_RCGCSSI 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_RCGCI2C 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_RCGCCAN 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_RCGCADC 0x0000000B 0x00000003
    R SYSCTL_SYSCTL_RCGCACMP 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_RCGCPWM 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_RCGCQEI 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_RCGCEEPROM 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_RCGCWTIMER 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGCWD 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGCTIMER 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGCGPIO 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGCDMA 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGCHIB 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_SCGCUART 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGCSSI 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGCI2C 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGCCAN 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGCADC 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGCACMP 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGCPWM 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGCQEI 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGCEEPROM 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_SCGCWTIMER 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGCWD 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGCTIMER 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGCGPIO 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGCDMA 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGCHIB 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_DCGCUART 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGCSSI 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGCI2C 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGCCAN 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGCADC 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGCACMP 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGCPWM 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGCQEI 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGCEEPROM 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_DCGCWTIMER 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_PRWD 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_PRTIMER 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_PRGPIO 0x0000000B 0x000003FF
    R SYSCTL_SYSCTL_PRDMA 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_PRHIB 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_PRUART 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_PRSSI 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_PRI2C 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_PRCAN 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_PRADC 0x0000000B 0x00000003
    R SYSCTL_SYSCTL_PRACMP 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_PRPWM 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_PRQEI 0x0000000B 0x00000000
    R SYSCTL_SYSCTL_PREEPROM 0x0000000B 0x00000001
    R SYSCTL_SYSCTL_PRWTIMER 0x0000000B 0x00000000
    

    In emulation a breakpoint at the if (HWREG... gives attached file.

    I will look up the interrupt now.

    Thanks for your inputs.

    I originally wanted to protect against putting MOSC dependent app on a PIOSC only device.  But recently we had another set of controllers that had the flux clean process change.  The processors work well for months, then the flux becomes active again.  The flux hiding under the belly of the MOSC.  Eventually the MOSC croakes and processor locks up.  I would prefer to go into a limp mode and log the fault.

  • Hello John,

    Actually there is an errata for clock failure once it has been started successfully (which seems to be the case you have mentioned). Can you check the latest errata document (section SYSCTL#03)?

    Regards

    Amit

  • Amit Ashara said:
    Can you check the latest errata document (section SYSCTL#03)?

    Been there, done that.  That is why I have bailed out of the emulator to test on a real system.  It seems reseting the emulator falls under the "the MOSC was once working now is not" clause.

    I also believe this errata point blocks using the feature to identify the "flux gone bad under the MOSC" issue.

    Is the System_Control_ISR, found in startup_ccs.c, the ISR used?

  • My code now begins with:

        HWREG(SYSCTL_MISC) |= 0x0000008;
        HWREG(SYSCTL_IMC)  |= 0x0000008;
        HWREG(SYSCTL_MOSCCTL) = SYSCTL_MOSC_VALIDATE | SYSCTL_MOSC_INTERRUPT;
    

    But I do not hit System_Control_ISR (which pushes a message on the CAN buffer and should be seen on the CAN bus, then goes into a forever loop.)

    I am still lost as to why I sense a MOSC failure.  I am adding this detection code to a FW base that has been running off of the MOSC for years.

    Should I be?:

    1. Clear RIS.MOSCPUPRIS
    2. Clear RIS.MOFRIS
    3. Enable MOSC
    4. Wait for RIS.MOSCPUPRIS to go high
    5. Check RIS.MOFRIS

    Somehow, RIS.MOFRIS goes high on a system that definately has MOSC operating well.

    There must be some test FW for this feature to use as an example.  Is there?

  • It is time to give up on this feature.  I hope TI folks are informed that it does not work.

    I have now instrumented my code heavily, saving register values into RAM, then sending out on CAN bus for analysis.  What I learned was:

    1) values of registers in an emulated system and non-emulated system are different on startup.  For emulated the CPU comes out of hibernation, or a cold start.  For non-emulated, either emulation starts, or a pause->reset CPU->restart cycle is completed.  Conclusion is that you really cannot emulate this feature.

    2)MOSC oscillator failure flag is always set after the SysCtlClockSet call below.  Whether in emulation or not.  In the code below RISA = 0x00, RISB = 0x0148, i.e., MOSC has had time to power up, PLL has had time to lock and the MOSC has failed.  The MOSC is driving the CAN bus and is putting out plenty of traffic at the correct baud.  Calling SysCtlClockSet a second time does not trigger an update of RIS.  I find nothing in documentation on how to trigger an update of RIS.

    3) Never saw any evidence of ending up in any interrupt, even though the MOFRIS interrupt is enabled.

        RISA = HWREG(SYSCTL_RIS);
        if (HWREG(SYSCTL_RIS) & 0x00000008 ) {
            SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_INT);
            MOSC_Failed = TRUE;
            // Clear RIS.MOFRIS and MISC.MOFMIS, by setting MISC.MOFMIS
            HWREG(SYSCTL_MISC) |= 0x0000008;
        }
        else {
            SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                               SYSCTL_XTAL_20MHZ);
        }
        RISB = HWREG(SYSCTL_RIS);

    I am using G4 silicon.

     

  • I ran around the table one more time and turned off the SYSCTL_MOSC_INTERRUPT bit.  The code in emulation now jumps to the NMI ISR as expected if the MOF bit gets set.  So the main problem is that the call to SysCtlClockSet always sets the MOF bit.  I tried turning on the MOSC earlier in the process to give it time to stabilize, but that did not help.

  • Hello John

    The System Control Interrupt has to be mapped in the startup_ccs.c file.

    Now when the MOSC is already being used, then calling SysCtlClockSet will not be useful unless the clock source is being changed. I will run the same experiment in my setup too check if I can get an Interrupt.

    Regards

    Amit

  • Amit,

    Thanks for putting time into this.  I do actually hope it is a gap in my programming rather than in the silicon.  This is actually a powerful feature.  OSC are delicate and can be corrupted by solder and cleaning residue.  This feature would not only help identify this issue, but allows a work around so a limp mode can be entered and the fault logged.

    I confirmed that the system control interrupt is mapped and at the correct position in the vector table.

    I went into emulation after setting IMC = 0xD4A, i.e. every possible ISR source enabled.  The MOSCPUPRIS bit is usually set at some point and I thought at least this should drive me into that interrupt.  I set a BP in the ISR.  Let the program run, did not hit the ISR.  My registers are RIS = 0x00000100, IMC = 0x00000D4A, MISC = 0x000000000.

    I leave emulation and just run, and the FW is responsive.  As the ISR goes into a forever loop, this indicates that the ISR is not hit in normal running.

    Conclusion:  I cannot get the device to jump to the SYS CTL ISR for any reason.

    Is the interrupt driven by the transition or level of the bit in RIS?  I.e., if the bit is set in RIS and then I set the corresponding bit in IMC, does an interrupt happen?  Or does the IMC bit have to be set when the RIS bit is set to get an interrupt?

    Regards,

    John