Debugging LF/HF Clock Output

As mentioned in the CC23xx SimpleLink Wireless MCU Technical Reference Manual, the 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 CC23xx and DIO27 for CC27xx observing the HF crystal or LF crystal clock signals, for example with a logic analyzer.

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

Map HF or LF crystal clock to DIO19 for CC23xx
 /*******************************************************************************
 * 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 CC27xx the following code snippet is used:

Map HF or LF crystal clock to DIO19 for CC27xx
 /*******************************************************************************
 * 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 CC23xx SimpleLink Wireless MCU Technical Reference Manual 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.

../_images/syscfg_power_policy_do_wfi_cc2340.png

Power Policy Function in SysConfig

Note

The LF crystal clock is permanently enabled in standby mode.