
.. _DEBUG_lf_hf_clock_output:

Debugging LF/HF Clock Output
============================

.. ifconfig:: device != 'cc23xx'

.. to be added

.. ifconfig:: device == 'cc23xx'

As mentioned in the |TRM|, the :term:`DTB` can be used to access
internal signals. The LF (Low Frequency) and HF (High Frequency) crystal clock
signals can be mapped to pins on the LaunchPad for signal debugging, for
example to analyze the clock accuracy or to correlate against sniffer log
events.

The code snippets below shows how to use DIO19 for |DEVICELOW| and
DIO27 for |DEVICEHIGH| observing the HF crystal
or LF crystal clock signals, for example with a logic analyzer.

.. _debugging-lf-hf-clock-cc23xx:

Initialize these IOs in your ``main`` function with the following content:

.. code-block:: c
   :caption: Map HF or LF crystal clock to DIO19 for |DEVICELOW|

    /*******************************************************************************
    * INCLUDES
    */
    #include <ti/drivers/GPIO.h>
    #include DeviceFamily_constructPath(inc/hw_types.h)
    #include DeviceFamily_constructPath(inc/hw_memmap.h)
    #include DeviceFamily_constructPath(inc/hw_ckmd.h)
    #include DeviceFamily_constructPath(inc/hw_ioc.h)
    #include DeviceFamily_constructPath(inc/hw_pmctl.h)
    
    // ...
    
    int main()
    {
        // ...
        
        /*
         * Add the following after Board_init();
         * Be sure IOID used below is not used by any entries in PIN or
         * GPIO tables from the board files.
         * The clock source can be switched with constant clockSrc.
         */
        
        uint8_t clockSrc = 0xC; //for HF crystal clock divided by 8
        //  uint8_t clockSrc = 0xF; //for LF crystal clock
        
        // drive output low first
        GPIO_setConfig(19, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
        
        // Configure the IOC.IOC19.PORTCFG MMR to select DTB
        HWREG(IOC_BASE + IOC_O_IOC19) &= ~IOC_IOC19_PORTCFG_M;
        HWREG(IOC_BASE + IOC_O_IOC19) |= IOC_IOC19_PORTCFG_DTB;
        
        // Make sure the DTB mux selects in IOC (and if required in
        // source clock IP) are reset that zero is driven on DTB0.
        // ULLSEL mux select (select CKMD)
        HWREG(IOC_BASE + IOC_O_DTBCFG) &= ~IOC_DTBCFG_ULLSEL_M;
        HWREG(IOC_BASE + IOC_O_DTBCFG) |= 0x1 << IOC_DTBCFG_ULLSEL_S; // 0x1 to route CKMD to DTB0
        
        // Enable IOC.DTBOE.EN0
        HWREG(IOC_BASE + IOC_O_DTBOE) &= ~IOC_DTBOE_EN0_M;
        HWREG(IOC_BASE + IOC_O_DTBOE) |= IOC_DTBOE_EN0_EN;
        
        // select which clock (CKMD) to output on DTB0 (DTB[0])
        HWREG(CKMD_BASE + CKMD_O_DTBCTL) &= ~CKMD_DTBCTL_CLKSEL_M;
        HWREG(CKMD_BASE + CKMD_O_DTBCTL) |= (clockSrc) << CKMD_DTBCTL_CLKSEL_S;
        
        // enable DTB output
        HWREG(CKMD_BASE + CKMD_O_DTBCTL) &= ~CKMD_DTBCTL_EN_M;
        HWREG(CKMD_BASE + CKMD_O_DTBCTL) |= CKMD_DTBCTL_EN;
        
        // ...
    }


For |DEVICEHIGH| the following code snippet is used:

.. code-block:: c
   :caption: Map HF or LF crystal clock to DIO19 for |DEVICEHIGH|

    /*******************************************************************************
    * INCLUDES
    */
    #include <ti/drivers/GPIO.h>
    #include DeviceFamily_constructPath(inc/hw_types.h)
    #include DeviceFamily_constructPath(inc/hw_memmap.h)
    #include DeviceFamily_constructPath(inc/hw_ckmd.h)
    #include DeviceFamily_constructPath(inc/hw_ioc.h)
    #include DeviceFamily_constructPath(inc/hw_pmctl.h)
    
    // ...
    
    int main()
    {
        // ...
        
        /*
         * Add the following after Board_init();
         * Be sure IOID used below is not used by any entries in PIN or
         * GPIO tables from the board files.
         * The clock source can be switched with constant clockSrc.
         */

        //uint8_t clockSrc = 0xC; //for HF crystal clock divided by 8
        uint8_t clockSrc = 0xF; //for LF crystal clock// drive output low first

        // drive output low first
        GPIO_setConfig(27, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);

        // Configure the IOC.IOC19.PORTCFG MMR to select DTB
        HWREG(IOC_BASE + IOC_O_IOC27) &= ~IOC_IOC27_PORTCFG_M;
        HWREG(IOC_BASE + IOC_O_IOC27) |= IOC_IOC27_PORTCFG_DTB;

        // Make sure the DTB mux selects in IOC (and if required in
        // source clock IP) are reset that zero is driven on DTB0.
        // ULLSEL mux select (select CKMD)
        HWREG(IOC_BASE + IOC_O_DTBCFG) &= ~IOC_DTBCFG_ULLSEL_M;
        HWREG(IOC_BASE + IOC_O_DTBCFG) |= 0x1 << IOC_DTBCFG_ULLSEL_S; // 0x1 to route CKMD to DTB0// Enable IOC.DTBOE.EN0

        // Enable IOC.DTBOE.EN0
        HWREG(IOC_BASE + IOC_O_DTBOE) &= ~IOC_DTBOE_EN0_M;
        HWREG(IOC_BASE + IOC_O_DTBOE) |= IOC_DTBOE_EN0_ENABLE;// select which clock (CKMD) to output on DTB0 (DTB[0])

        // select which clock (CKMD) to output on DTB0 (DTB[0])
        HWREG(CKMD_BASE + CKMD_O_DTBCTL) &= ~CKMD_DTBCTL_CLKSEL_M;
        HWREG(CKMD_BASE + CKMD_O_DTBCTL) |= (clockSrc) << CKMD_DTBCTL_CLKSEL_S;// enable DTB output

        // enable DTB output
        HWREG(CKMD_BASE + CKMD_O_DTBCTL) &= ~CKMD_DTBCTL_EN_M;
        HWREG(CKMD_BASE + CKMD_O_DTBCTL) |= CKMD_DTBCTL_EN; 
        
        // ...
    }


.. note::
   The clock source can be selected with the variable ``clockSrc``. Please
   refer to the DTBCTL register field description in the |TRM| for the
   clock source. The HF crystal clock should be mapped as a divided clock,
   as the IO pin output frequency is limited.

.. note::
   Alternatively DTB0 can be mapped to DIO12 by setting DTBCFG.PADSEL
   bit field to 0x5. Other pins cannot output DBT0 signals.

When the HF crystal clock divided by 8 is selected in the above example, the
output signal of 6 MHz can be observed (48 MHz / 8 = 6 MHz). When the LF
crystal clock is selected in the above example, then the output signal of 
32.768 kHz can be expected.

The HF crystal clock is automatically disabled when the device enters
standby mode and the clock is re-enabled when the device wakes up from
standby. As a result, only short bursts of HF crystal clock might be
observed in a typical Bluetooth LE application (such as **basic_ble**).
These bursts represent the active mode phases of the device. For enabling
permanent HF crystal clock output please select Power Policy Function
**PowerCC23X0_doWFI** in the **SysConfig - TI DRIVERS - Power** module.
Alternatively the device is also permanently in active mode during a debug
session in CCS.

.. _syscfg_power_policy_do_wfi_cc2340:
.. figure:: /debugging/resources/syscfg_power_policy_do_wfi_cc2340.png
   :align: center

   Power Policy Function in SysConfig

.. note::
   The LF crystal clock is permanently enabled in standby mode.