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:
/*******************************************************************************
* 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:
/*******************************************************************************
* 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.
Power Policy Function in SysConfig¶
Note
The LF crystal clock is permanently enabled in standby mode.