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.

CC2340R2: Selecting the External Clock source for Low Frequency clock

Expert 4425 points

Part Number: CC2340R2

Hi team,

I noticed that the function that selects the external clock source for the low frequency clock changed in the new SDK (v9.11). We had to copy this function and change the expected frequency to 32.768kHz in our code using SDK (v8.40).

The differences I want to ask about are:

1) Why is the setting of the mux now done first?

2) The setting up of LFK good interrupt is new

3) Enabling the LFK Good interrupt is new

Can you share any details on why these changes were made and if there are any effects on the older SDK (v8.40)?

//From new SDK(Simplink_lowpower_f3_SDK_9_11_00_18)
/*
 *  ======== PowerLPF3_selectEXTLF ========
 */
void PowerLPF3_selectEXTLF(void)
{
    /* Configure EXTLF to the right mux */
    GPIO_setConfigAndMux(PowerLPF3_extlfPin, GPIO_CFG_INPUT, PowerLPF3_extlfPinMux);

    Log_printf(LogModule_Power, Log_INFO, "PowerLPF3_selectEXTLF: EXTLF pin muxing configured");

    /* Set LFINC override to 31.25 kHz.
     *
     * The value is calculated as period in microseconds with 16 fractional
     * bits.
     * The EXTLF runs at 31.25 kHz -> 1 / 31250 Hz = 32 us.
     * 32 * 2^16 = 2097152 = 0x00200000
     */
    HWREG(CKMD_BASE + CKMD_O_LFINCOVR) = 0x00200000 | CKMD_LFINCOVR_OVERRIDE;

    /* Directly switch to EXTLF, LFTICK will be generated by HFOSC until EXTLF
     * is running.
     */
    HWREG(CKMD_BASE + CKMD_O_LFCLKSEL) = CKMD_LFCLKSEL_MAIN_EXTLF;

    /* Set EXTLF qualification function to be called by
     * PowerCC23X0_oscillatorISR(). This function will return true when getting
     * the LFCLKGOOD interrupt.
     */
    PowerLPF3_lfclkQualFxn = PowerCC23X0_extlfQual;

    /* Disallow standby until LF clock is running.
     * The PowerCC23X0_oscillatorISR() function will release the constraint once
     * PowerLPF3_lfclkQualFxn returns true.
     */
    Power_setConstraint(PowerLPF3_DISALLOW_STANDBY);

    /* Enable LFCLKGOOD interrupts */
    HWREG(CKMD_BASE + CKMD_O_IMSET) = CKMD_IMASK_LFCLKGOOD;
}
//From Old SDK (Simplelink_lowpower_f3_sdk_8_40_00_61)
/*
 *  ======== PowerLPF3_selectEXTLF ========
 */
void PowerLPF3_selectEXTLF(void)
{
    /* Set LFINC override to 31.25 kHz.
     *
     * The value is calculated as period in microseconds with 16 fractional
     * bits.
     * The EXTLF runs at 31.25 kHz -> 1 / 31250 Hz = 32 us.
     * 32 * 2^16 = 2097152 = 0x00200000
     */
    HWREG(CKMD_BASE + CKMD_O_LFINCOVR) = 0x00200000 | CKMD_LFINCOVR_OVERRIDE;
 
    /* Set LFCLK to EXTLF */
    HWREG(CKMD_BASE + CKMD_O_LFCLKSEL) = CKMD_LFCLKSEL_MAIN_EXTLF;
 
    /* Configure EXTLF to the right mux */
    GPIO_setConfigAndMux(PowerLPF3_extlfPin, GPIO_CFG_INPUT, PowerLPF3_extlfPinMux);
 
    /* Enable LFCLKGOOD */
    HWREG(CKMD_BASE + CKMD_O_IMSET) = CKMD_IMASK_LFCLKGOOD;
 
    /* Disallow standby until LF clock is running. Otherwise, we will only
     * vector to the ISR after we wake up from standby the next time since the
     * CKM interrupt is purposefully not configured as a wakeup source.
     */
    Power_setConstraint(PowerLPF3_DISALLOW_STANDBY);
 
    Log_printf(LogModule_Power, Log_INFO, "PowerLPF3_selectEXTLF: EXTLF selected");
}

Best,
Luke

  • Update:

    From testing today, the new SDK requires the new PowerLPF3_selectEXTLF() function to be called or it will not detect the loss of the low frequency clock.  It had changed from the prior SDK and we had not updated our selectEXTLF() function for the newer version of the SDK.

    The external low frequency clock signal that we use is at 32.768KHz.  The PowerLPF3_selectEXTLF() function expects a clock signal of 31.25KHz. We created a function called selectEXTLF() that was exactly the same as PowerLPF3_selectEXTLF() function except it expects a clock frequency of 32.768 KHz.

    The PowerLPF3_selectEXTLF() function now sets a local static function as a call back function for the PowerCC23X0_oscillatorISR 

        /* Set EXTLF qualification function to be called by PowerCC23X0_oscillatorISR(). This function will return true when getting the LFCLKGOOD interrupt.

    Now that I see the new PowerLPF3_selectEXTLF() function is a bit more tied to the PowerCC23X0.c file, I am wondering if I could call the existing PowerLPF3_selectEXTLF() and then change to the expected frequency immediately afterward. See below:

        PowerLPF3_selectEXTLF();
        /* Set LFINC override to 32.768 kHz.
         * The value is calculated as period in microseconds with 16 fractional bits.
         * The EXTLF runs at 32.768 kHz -> 1 / 32,768 Hz = 30.5176 us.
         * (1 / 32,768) * 2^16 = 2,000,000 = 0x001E8480 */
        HWREG((uint32_t)CKMD_BASE + CKMD_O_LFINCOVR) = 0x001E8480u | CKMD_LFINCOVR_OVERRIDE;


    This would mean that the value would be set incorrectly for a few clock cycles. Are there any concerns?

    And is it okay to change the value of this register after PowerLPF3_selectEXTLF() is called?

    And is it okay to set this register without disabling interrupts or anything else like that?

    Best,
    Luke

  • Hey Luke,

    Thanks for reaching out! I will take a look at this and get back to you.

    In the meantime, I took a quick look and it seems like the newer SDKs (9.14) uses a different implementation than the one found in 9.11. Have you tested the implementations found in the later sdks?

    Best Regards,

    Tarek D

  • Hi Tarek,

    They pulled down the latest SDK and compared the PowerCC23x0.c and .h files to the ones in their SDK (9_11_00.18). Just one change and it was with the HFXT fault.

            /* If a HFXT fault or trackrefloss has occurred, the HFXT is
             * restarted.
             * When the HFXT is started, a "disallow standby" constraint is set, and
             * it is released when the HFXT has started (when getting the AMPSETTLED
             * signal). However, if an HFXT fault occurs while waiting for
             * AMPSETTLED, then the HFXT will be re-started setting a new constraint
             * without releasing the previous one. The constraint will end up
             * getting set twice but only released once (assuming the AMPSETTLED
             * signal is generated after the re-start).
             * To prevent this asymmetry, add a check to release the constraint if
             * the system is still waiting for the AMPSETTLED signal before
             * restarting the HFXT.
             */
            if (((maskedStatus & CKMD_MIS_AMPSETTLED_M) == 0U) &&
                ((HWREG(CKMD_BASE + CKMD_O_IMASK) & CKMD_IMASK_AMPSETTLED_M) == CKMD_IMASK_AMPSETTLED_M))
            {
                Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
            }
     

    They are still trying to understand the LFOSC and how far it might be from 32.768KHz and how far it might drift due to temperature. Is it accurate enough to support BLE timing, events, etc.? Does the device 48MHz crystal continuously "correct" the 32kHz RC to keep the drift low enough while running? How about when the device is in sleep state and the crystal is off?

    Best,
    Luke

  • Hey Luke,

    The LFOSC can be used as the sleep clock, however, I would highly recommend modifying the SCA (sleep clock accuracy) and setting it to a higher ppm, since it is not as accurate.

    You can modify the SCA using the HCI command HCI_EXT_SetSCACmd().

    I do believe a correction does happen, and a "clock loss" soft reset will occur if the clock continues to drift.

    Best Regards,

    Tarek D

  • Hi Tarek and Luke,

    I noticed that this question had changed to using the LFOSC and that is not what this thread of questions are about.  The question we had about the use of LFOSC is being addressed in the related topic "CC2340R2:Internal LFOSC Accuracy".

    This item is about using an external clock signal EXTLF.  As noted above, the implementation in the power module had changed after Simplelink_lowpower_f3_sdk_8_40_00_61. With Simplelink_lowpower_f3_sdk_8_40_00_61, we were able to configure this to work with a input frequency of 32.768KHz.

    Now we need to get this to work with the SDK, Simplelink_lowpower_f3_sdk_9_11_00_18.  Above describes the issue we have been running into, loss of the clockloss feature.

    What is the best way to use Simplelink_lowpower_f3_sdk_9_11_00_18 and an external LF clock signal of 32.768KHz?

    Best Regards,

    Rick 

  • Hey Rick and Luke,

    Since we have moved this conversation to email, I will close this thread