Debugging¶
Debug Interfaces¶
The CC23xx platform supports SWD interfaces. Debug probe that support SWD like the TI XDS110 can work natively with the CC23xx. The hardware resources included on the devices for debugging are listed as follows. Not all debugging functionality is available in all combinations of debug probe and IDE.
Flash Patch and Breakpoint Unit (FPB) - 6 instruction comparators, 2 literal comparators
Data Watchpoint and Trace Unit (DWT) - 5 watchpoints on memory access
Instrumentation Trace Macrocell (ITM) - 32 x 32 bit stimulus registers
Trace Port Interface Unit (TPIU) - serialization and time-stamping of DWT and ITM events
XDS110 Debug Probe¶
The CC23xx LaunchPad support a 20-pin LP-EM debug connector, and the XDS110ET LaunchPad is the assumed debug probe for most development.
The XDS110 is the latest entry level debug probe (emulators) for TI embedded processors. Designed to be a complete solution that delivers JTAG and SWD connectivity at a low cost, the XDS110 is the debug probe of choice for entry-level debugging of TI microcontrollers, processors and SimpleLink devices. Also, both Core Processor and System Trace are available for all Arm and DSP devices that support Embedded Trace Buffer (ETB).
It is also possible to buy the XDS110 JTAG Debug Probe or use the XDS110 existing on-board another SimpleLink LaunchPad.
Segger J-Link Probes¶
The CC23xx platform also supports Segger J-Link Probes. These probes support
standard debug and flash operations on the CC23xx. To create a J-Link compatible image,
the crc_tool
resource included in {SDK_INSTALL_DIR}/tools/common/crc_tool
should be
used to calculate the CRC. This can be done through the use of a post-build step.
The add_crc_to_elf_file_ccfg section, provides details on how to use the
crc_tool
along with code snippets showcasing its use.
The J-Link Real Time Transfer (RTT) feature may be used with the CC23xx platform when using a J-Link probe by following the guidance outlined in the Segger Real Time Transfer (RTT) website.
To obtain a Segger J-Link probe, please visit the Segger website.
Configuring Debugger in Code Composer Studio¶
If only one debug probe is attached, CCS will automatically select the
connected debug probe when a debug session is started. You can start a debug
session by clicking the debug icon on the toolbar.
If more than one debug probe is attached when a debug session is started, CCS will prompt you to select a debug probe as seen in Figure 32. CCS will save the selected debug probe in the target configuration for the project.

Figure 32. CCS Probe Selection¶
To set or change the selected debug probe for a project, it is necessary to set the serial number for the probe in the project’s target configuration.
|
![]() |
|
![]() |
|
![]() |
|
![]() |
Find The Serial Number¶
To find the serial number for XDS110 debug probe, open a command prompt and run
the xdsdfu.exe
command for your CCS version, e.g.
<CCS_INSTALL_DIR>\ccs\ccs_base\common\uscif\xds110\xdsdfu.exe -e
. For
UniFlash, the command will be:
<UNIFLASH_INSTALL_DIR>\deskdb\content\TICloudAgent\win\ccs_base\common\uscif\xds110\xdsdfu.exe -e
.
This will enumerate all the attached XDS110 debug probes. This should result in
output like the following.
C:\>c:\ti\ccs1210\ccs\ccs_base\common\uscif\xds110\xdsdfu.exe -e
USB Device Firmware Upgrade Utility
Copyright (c) 2008-2019 Texas Instruments Incorporated. All rights reserved.
Scanning USB buses for supported XDS110 devices...
<<<< Device 0 >>>>
VID: 0x0451 PID: 0xbef3
Device Name: XDS110 Embed with CMSIS-DAP
Version: 3.0.0.22
Manufacturer: Texas Instruments
Serial Num: LS420073
Mode: Runtime
Configuration: Standard
Found 1 devices.
C:\>
Note
More information of the tool can be found in
<CCS_INSTALL_DIR>\ccs\ccs_base\common\uscif\xds110\XDS110SupportReadMe.pdf
For XDS100 series debug probes, open a command prompt and run the
xds100serial.exe
command for your CCS version, e.g.
<CCS_INSTALL_DIR>\ccs\ccs_base\common\uscif\xds100serial.exe
. This should result
in output like the following:
C:\>c:\ti\ccs1210\ccs\ccs_base\common\uscif\xds100serial.exe
Scanning for XDS100 emulators...
VID/PID Type Serial # Description
0403/a6d1 XDS100v3 06EB12213144 Texas Instruments XDS100v3
C:\>
Configure the Serial Number¶
Open the xdsdfu.exe
command for your CCS version, e.g.
<CCS_INSTALL_DIR>\ccs\ccs_base\common\uscif\xds110\xdsdfu.exe -m
<CCS_INSTALL_DIR>\ccs\ccs_base\common\uscif\xds110\xdsdfu.exe -s LS470000 -r
These will first switch XDS110 to DFU mode if it is already in runtime mode, then set the serial number to the LS470000. The output should be like the following.
C:\>c:\ti\ccs1210\ccs\ccs_base\common\uscif\xds110\xdsdfu.exe -m
USB Device Firmware Upgrade Utility
Copyright (c) 2008-2019 Texas Instruments Incorporated. All rights reserved.
Scanning USB buses for supported XDS110 devices...
<<<< Device 0 >>>>
VID: 0x0451 PID: 0xbef3
Device Name: XDS110 Embed with CMSIS-DAP
Version: 3.0.0.22
Manufacturer: Texas Instruments
Serial Num: L1100JU9
Mode: Runtime
Configuration: Standard
Switching device into DFU mode.
C:\>c:\ti\ccs1210\ccs\ccs_base\common\uscif\xds110\xdsdfu.exe -s LS470000 -r
USB Device Firmware Upgrade Utility
Copyright (c) 2008-2019 Texas Instruments Incorporated. All rights reserved.
Scanning USB buses for supported XDS110 devices...
Setting serial number to "LS470000"...
C:\>
Program Board ID on LP-EM Boards¶
It is possible that in some very rare circumstances different LP-EM Boards are with the same Board ID or with empty Board ID. In this case:
UniFlash may not identify the device correctly
CCS may not identify the board correctly
Programming the different Board ID to each board should help. It can be done also
by open a command prompt and run the xdsdfu.exe
command. Plug only one LP-EM
board to the host PC. Unplug all other boards. For CCS
version, e.g. <CCS_INSTALL_DIR>\ccs\ccs_base\common\uscif\xds110\xdsdfu.exe -p
.
For UniFlash, the command will be:
<UNIFLASH_INSTALL_DIR>\deskdb\content\TICloudAgent\win\ccs_base\common\uscif\xds110\xdsdfu.exe -p
.
This should result in output like the following:
C:\>c:\ti\ccs1210\ccs\ccs_base\common\uscif\xds110\xdsdfu.exe -p LS47XXXX
USB Device Firmware Upgrade Utility
Copyright (c) 2008-2019 Texas Instruments Incorporated. All rights reserved.
Scanning USB buses for supported XDS110 devices...
Setting serial number prefix to "LS47XXXX"...
The serial prefix was set in EEPROM.
Power cycle the XDS110 for the change to take effect.
After running the command, unplug and re-plug the LP-EM board to the host PC to acknowledge the new Board ID to the host PC.
Getting started with CCS debug interface¶
This section describes the debug interface offered by CCS.
Note
More extensive documentation is provided in the CCS Debug Environment Guide.
Start a debug session¶
To start a debug session, click on the debug icon. If enabled to do and required, this will trigger a software build. It will also automatically download the binary on the CC23xx device.
Note
The small arrow next to the debug button offers the possibility to modify the Debug Configurations.
If needed, make sure to select the proper process in the Debug View.

Reset the device while debugging¶
TI recommends to use the default reset command (i.e. click on the
button or use the shortcut
Ctrl+Shift+R
).
Using other reset commands may lead to unexpected device behavior.
Build and flash the device while debugging¶
To rebuild the code and automatically flash the device during a debug session
press the build button. Then press “yes” in the dialog box
you can also click on the Reload Program
button (shortcut
Ctrl+Alt+R
)
Breakpoints¶
Comparators in the Flash Patch and Breakpoint Unit (FPB) of the CC23xx LaunchPad are used to break on an instruction fetch. This can be used to patch a function as it is fetched from instruction memory. Or these comparators can be used to supply a Breakpoint (BKPT) instruction to the CPU. These instructions halt the processors operation, waiting for the debug probe.
Considerations¶
While breakpoints are a useful tool for debugging code online, they have the possibility of altering the execution flow of a piece of code.
Breakpoints and Timing¶
Synchronous RF protocols are timing sensitive. Breakpoints can easily halt the execution long enough to lose network timing and break the link.
To still be able to debug, place breakpoints as close as possible to where the relevant debug information can be read or step through the relevant code segment to debug.
After you hit a breakpoint and read out the necessary debug information, it is recommended that you reset the device and re-establish the connection.
Breakpoints and Optimization¶
When compiler optimizations are enabled, toggling a breakpoint on a line of C code may not result in the expected behavior. Some examples include the following.
Code is removed or not compiled in
Toggling a breakpoint in the IDE results in a breakpoint somewhere other than the intended line. Some IDEs disable breakpoints on nonexistent code.
Code block is part of a common subexpression
A breakpoint might be trigged from a function or piece of code near the marked line. This might have been due to the compiler reusing sections.
An if clause is represented by a conditional branch in assembly
A breakpoint inside an if clause always breaks on the conditional statement, even when the condition is not true.
TI recommends selecting an optimization level as low as possible when debugging. See Optimizations for information on modifying optimization levels.
Note
Due to limitation of Cotex-CM0+, the number of breakpoints for CC23xx devices is 4. Check breakpoints limitation of ARM Cortex-CM0+. During programming stage, debugger will use 3. Breakpoints set by application will be ignored if more than one breakpoint is used by the application. It is possible to gain one more breakpoint back by implementing the following steps. Right click on the project, go to Debug As->Debug Configuration->Target, unchecked ‘Enable CIO function use’.

Breakpoints in CCS¶
Note
CCS reserves one hardware breakpoint for instruction stepping.
To toggle a breakpoint, do any of the following.
Double-click the area to the left of the line number.
Press
Ctrl
+Shift
+B
.Right-click on the line.
A breakpoint set on line 207 looks like the following.

Figure 33. Breakpoint on line 207. Debugger halted at start of main().¶
For an overview of the active and inactive breakpoints, click on View
→ Breakpoints
.

Figure 34. List of breakpoints. Right-click to edit options, or de-select to deactivate.¶
To set a conditional break, do as follows.
Right-click the breakpoint in the overview.
Choose Properties.
When debugging, Skip Count and Condition can help skip a number of breaks or only break if a variable is a certain value.
Note
Conditional breaks require a debugger response and may halt the processor long enough to break an active RF connection, or otherwise disrupt timing on the debug target.
Watching Variables and Registers¶
Debuggers offer several ways of viewing the state of a halted program. Global variables are statically placed during link-time and can end up anywhere in the RAM or Flash of the chip. These variables can be viewed when then target is halted by the debugger through the Watch and Expression windows.
Unless removed due to optimizations, global variables are always available in these views. Local variables or variables that are only valid inside a limited scope are only viewable in that scope. Such variables can also be viewed with the Watch or Expression views, and may also be automatically displayed when breaking or stepping through code.
Considerations¶
Local variables are often placed in CPU registers and not on the stack. These variables also have a limited lifetime even within the scope in which they are valid. Depending on the optimization performed, a variable placed in a register may not have a cohesive view of the current state of the variable. Some possible solutions are:
Move the variable to global scope, so it remains accessible in RAM.
Make the variable volatile, so the compiler doesn’t place the value in a register.
Make a shadow copy of the variable that is global and volatile.
Variables in CCS¶
You can view Global Variables by doing either of the following.
Select
View
→Expressions
.Select a variable name in code.
Right-click and select Add Watch Expression.

Figure 35. Variable watch window. Note that you can cast values, get address and sizeof, etc.¶
Select
View
→Variables
toauto-variables
that are present at the current location when stepping through code.

Figure 36. Local variables. This screenshot is taken during execution of an application function.¶
Memory Watchpoints¶
As mentioned in Debug Interfaces, the Data Watchpoint and Trace Unit (DWT module) contains four memory watchpoints that allow breakpoints on memory access. The hardware match functionality looks only at the address. If intended for use on a variable, the variable must be statically allocated.
Note
If a data watchpoint with value match is used, two of the four watchpoints are used.
Watchpoints in CCS¶
Warning
Watchpoint are not available on CC2340R5 and CC2340R21
Right-click on a global variable.
Select
Breakpoint
→Hardware Watchpoint
.Go to the list of breakpoints (
View
→Breakpoints
).Right-click and edit the Breakpoint Properties to configure the watchpoint.

Figure 37. Adding a watchpoint on a variable.¶
This example configuration ensures that if 0x42 is written to the memory location for Characteristic 1 in the Bluetooth Low Energy basic_ble example project the device halts execution.

Figure 38. Configuring a hardware watchpoint to break on 8-bit write with value 0x42.¶
Enabling Logging in CCS¶
The log
driver may be used to easily add debug logging capabilities
to any project. The main benefit of the log
driver is operates
entirely through JTAG which means that no UART peripherals are necessary
to enable the logging functionality. In other words, you do not have
to use up a UART peripheral or modify your project’s UART operation
to enable debug logging for your debugging purposes.
Setting up the Logging Functionality¶
To start, import the desired project into CCS.
For this example, Basic BLE project will be used.
Next, add
${COM_TI_SIMPLELINK_LOWPOWER_F3_SDK_INSTALL_DIR}/source/ti/log/lib/ticlang/m0p/log_cc23x0r5.a
to the File Search Path, which is found by right clicking the project →Properties
→Build
→Arm Linker
→File Search
. Click the add icon to add the path. The properties tab should look like the image below when completed correctly. After adding the file path, click Apply and Close.Add
ti_log_Log_ENABLE
to the Predefined Symbols. This is also found within the properties of the project. Right click the project →properties
→Build
→Arm Compiler
→Predefined Symbols
. Add this with the paper icon with the green plus. The properties tab should look like the image below when completed correctly. After adding the predefined symbol, click Apply and Close.
Setting up Log Modules¶
Open the Basic BLE SysConfig file. The logging module is configured through SysConfig. Under
LOGGING
, is a section for log modules. Here, the log modules will be added. Once in the Log Modules SysConfig section, click onADD
to add a Log Module instance. Name the moduleLogModule_App1
. Within this module, make sure theEnable Module
check box is checked. Next check theEnable Level DEBUG
,Enable Level VERBOSE
, andEnable Level INFO
. Make set the sink to/ti/log/LogSinkBuf
and ensureLogger Sink Instance
is set toCONFIG_ti_log_LogSinkBuf_0
.The module will look like the following if the previous steps are followed.
Within the
Global Parameters
section checkGlobal Enable Module
, then under theGlobal Log Level Configuration
subsection, checkEnable Level DEBUG
,Enable Level VERBOSE
, andEnable Level INFO
Check
LOG SINKS
module in SysConfig, and verify the name is properly set:To test the log function, add the code below into the main function.
1Log_printf(LogModule_App1, Log_DEBUG, "Hello world");
Add also the following include:
1#include <log/Log.h>
Once this is done, debug and flash the program to the board. While the board is in debug mode, you may open the log by going to
Tools
→Runtime Object View
. After ROV is open, click onLogSinkBuf
within ROV, and set theLogSinkBuf
toRecords
, and then click the continuous refresh button to keep the log constantly updating. It should look like this:
This completes the basic set up for the logging functionality. Additionally, more Log_printf
can be added in various locations to indicate different tasks. The debug level may be changed
or outright disabled during debugging depending on which parts of the programs you want to debug
or would like to receive messages for.
For more information on the log function, make sure to reference the Log Example for a drivers-only example that contains the logging functinoality. The readme for the example also provides valuable insight into how the log driver works and how you can use it in your custom project.
Runtime Object Viewer¶
Debuggers may include the Runtime Object Viewer (ROV) plug-in that provides insight into the current state of FreeRTOS, including task states, stacks, and so forth.
This section discusses some ROV views useful for debugging and profiling.
Viewing the State of Each Task¶
The Task Detailed
view is useful for seeing the state of each task and its
related runtime stack usage. This picture below shows the state the first time the
user-thread is called.

Figure 39. ROV Task Detail View¶
The following table explains the column in ROV Task Detail View
Address |
The memory location of the |
TaskName |
The name of the entry function of the task. |
Priority |
The RTOS priority for the task. |
State |
Current state of the task. |
StackSize |
The size of the runtime stack, configured when instantiating a task. |
StackPeak |
The maximum run-time stack memory used based on watermark in RAM, where the stacks are prefilled with 0xBE and there is a sentinel word at the end of the run-time stack. |
StackLimit |
The logical top of the runtime stack of the task. |
Note
Function calls may push the stack pointer out of the run-time stack, but not actually write to the entire area. A stack peak near stackSize but not exceeding it may indicate stack overflow.
ROV in CCS¶
To access the ROV while in a debug session in CCS:

Attention
You can enable live watch on ROV to automatically retrieve up to date information, however, the refreshing rate is not frequent. You can also pause the debugger or manually click refresh button to enforce a ROV information update.
Using the Memory Browser¶
Open the memory browser at View
→ Memory Browser
to explore the memory on the CC23xx. In
CCS, you can index by address or by symbol name.
Basic BLE Task’s stack (Note the |
GAPRole Task’s stack has probably overflowed as it is completely filled. |
![]() |
![]() |
The solution in this case would be to increase the stack size for the failing
task and see what the stack peak really is. The stackPeak
reported in
rov_task_detailed_cc2340
is relying on how many watermark bytes
are overwritten, so it can’t know how much the overrun amounts to.

Because stacks are utilized from higher addresses towards lower addressed (upwards in the picture), stacks that overrun will tend to overwrite data at locations immediately before the stack.
Read CC2340R5 MAC Address via UniFlash¶
The MAC address of a specific CC2340R5 device may be read through UniFlash. This can be done through the UniFlash GUI or through the UniFlash CLI.
Prerequisites¶
The user is expected to have/do the following:
CC23xx
A computer running a supported operating system listed in the Release Notes
Latest version of UniFlash
Read the UniFlash QuickStart Guide located in
{UNIFLASH_INSTALL_DIR}/docs/quick_start_guide/uniflash_quick_start_guide.html
Reading MAC Address through UniFlash GUI¶
Reading the MAC address through the UniFlash GUI is most useful when the MAC address needs to be read once for testing or documentation. If the value needs to be read as part of some automation process or manufacturing process, then the CLI method discussed in Reading MAC Address through UniFlash CLI. is recommended.
This step-by-step guide will help you to read the MAC address written to your device through the UniFlash GUI.
While the CC23xx is connected to your computer, open UniFlash.
Launch the device configuration of the CC23xx by using the auto-detect feature or by manually searching for the CC23xx in the
New Configuration
section and clicking onStart
.Once the device configuration has been launched, navigate to to the
Memory
tab on the left and click onRead Target Device
On the
Address
search bar on the top left, type0x4E000058
and click onGo
The device memory will be read and the
0x4E000058
address will be highlighted in the browser.The highlighted data will contain the MAC address of the device.
Reading MAC Address through UniFlash CLI¶
If the MAC Address must be read due to a fabrication workflow or as part of an automated testing process, then reading the address through the UniFlash Command Line Interface (CLI) will likely be the most useful method.
This step-by-step guide will help you to read the MAC address written to your device through the UniFlash CLI
While the CC23xx is connected to your computer, open UniFlash.
Launch the device configuration of the CC23xx by using the auto-detect feature or by manually searching for the CC23xx in the
New Configuration
section and clicking onStart
.Once the device configuration has been launched, navigate to to the
Standalone Command Line
tab on the left and click onGenerate Package
. This may take a few minutes.On the save the generated package to a known location (for example,
C:\ti
) and unzip the archive that the known location. The newly extracted folder, should look like the following image:Run the
one_time_setup.bat
script. This script will generated all the necessary setup-files to use the CLI.Open a command-line and navigate to the newly extracted folder.
Type and run the following command:
.\dslite-Cortex_M0P.bat --mode memory --config .\user_files\configs\cc2340r5.ccxml --range=0x4E000058,1 --output=result.hex
The command will read one entire word at memory address
0x4E000058
which will contain the MAC address of the device. The read data will be written to aresult.hex
file located in the extracted folder.The file may be read through a hex viewer/editor program. Looking into the file, we see the following:
The commands specified in this section may be utilized in scripting languages to allow for easy automation.
More information about the UniFlash Command Line Interface may be found in the Quick Start Guide included with your UniFlash installation.
Connect the debugger to a running target¶
Connecting the debugger to a target can help when you want to see the status of your target after it has been running for several hours, or even days; or if you cannot reproduce a crash with the debugger attached. Once the debugger connected to the target, all the usual functionalities (break points, step-by-step, variable view, memory view…) are available.
This step-by-step guide will help you to configure CCS in order to connect to a running target
While the CC23xx is running the desired project, open CCS.
Open the Target Configurations window by click on View → Target Configurations.
In the Target Configurations window, expand the Projects folder.
Expand your project within the Projects folder inside the Target Configurations window.
Expand the targetConfigs folder.
Right click on CC2340R5.ccxml and click on Launch Selected Configuration
After a few seconds, CCS will connect to the target and the core will be visible in the Debug window.
Right click on the core and select Connect Target
Click on Run → Load → Load Symbols…
Click on Browse Project.
Select your project’s out file and press OK.
Press OK on Load Symbols window.
At this point you are connected to the target and should see where in the project the target is currently located.
Optimizations¶
Compiler optimizations are great for saving space or speeding up execution. However, these optimizations can be very difficult to debug around. There are multiple levels at which optimization can be turned on or off.
Project-wide optimization settings are the most general. Sometimes, given the constraints of the device, it is impossible to lower the size optimization level. File-wide optimization settings can be used like project-wide optimizations to turn on or off certain settings. The most granular control is using compiler directives to control optimization at a function level.
Optimizations in CCS¶
Project-Wide Optimizations¶
Open the project optimization settings by going to Project Properties
→ CCS Build
→ ARM Compiler
→ Optimization

Figure 40. Project-level optimization setting in CCS¶
Single-File Optimizations¶
Note
Do single-file optimizations with care because this also overrides the project-wide preprocessor symbols.
Right-click on the file in the Workspace pane.
Choose Properties.
Change the optimization level of the file using the same menu in the CCS project-wide optimization menu.
Single-Function Optimizations¶
Warning
Care must be taken when using pragmas, since they are very specific to the toolchain and may render non-reusable code.
Important
- The TI ARM Clang compiler does not support single-function optimizations. Use Single File optimizations instead.
For additional details, check section 3 of the TI ARM Clang User’s Guide.
#pragma GCC push_options
#pragma GCC optimize ("O0")
static void myFunction(int number)
{
// ...
return yourFunction(other_number);
}
#pragma GCC pop_options
Deciphering Exceptions¶
Several possible exception causes exist. If an exception is caught, an
exception handler function can be called.
Arm Cortex User Guide
describes more about exception handler.
There are ways to determine whether the hang up is due to the hard
fault. One is to watch the Program Counter (PC)
register which will indicate operation in the
hard fault handler. The second method is to watch the special-purpose program status registers (xPSR)
.

Figure 41. Exception Registers¶
Debugging RF Output¶
As mentioned in the CC23xx SimpleLink Wireless MCU Technical Reference Manual, the RF output can be mapped to pins on the LaunchPad for RF signal debugging. These pins are intended to be used when connecting an RF range extender. However, they can also help in instances where it is unclear if the device is transmitting or receiving in the right window.
On the CC23xx, the RF observables should be enabled through SysConfig.
In SysConfig -> TI DRIVERS
-> RCL
-> RCL Observables
,
For
Use Case
selectPA/LNA Pins
The settings for the
Additional RF GPIO Signals
should be automatically selected (RFEGPO0 (PA_EN)
andRFEGPO1 (LNA_EN)
)
The DIO the signal is outputted on can then be
configured under SysConfig -> TI DRIVERS
-> RCL
-> PinMux
LRF GPIO
should be left toLRF
RFEGPO0 Pin
should be set to the DIO wanted for the PA signal (Radio Tx)
RFEGPO0 Pin
should be set to the DIO wanted for the LNA signal (Radio Rx)

Figure 42. Configuration to set under SysConfig -> TI DRIVERS
-> RCL
to enable RF Observables¶
Debugging guide for serial interfaces¶
The aim of this chapter is to give some pointers on what to check if some issues are seen when using the UART, SPI, or I2C interfaces.
Note: TI only supports how to use the serial interface modules and the TI supplied drivers for these interfaces. TI are not able to help on the usage of a non-TI device connected to I2C, SPI or UART.
I2C¶
The I2C interface needs an external pull-up resistor. On the LauchPad these are 3.3 kOhm.
Measure the waveform on the I2C interface with an oscilloscope to verify the SCL and SDA levels
Monitor the interface with a logic analyzer. Check that data on the bus is the same as the wanted data.
Check the interface by reading out the device ID of the sensor.
Check the slave address. The I2C module uses a 7-bit address. The last 8th bit is the data direction bit. This last bit is appended automatically by the driver/HW. The Slave address given to the driver has therefore to be 7-bit.
Ensure that the readCount and writeCount is according to the register size used. If the result register in the sensor is 16-bit, the readCount has to be set to 2.
SPI¶
Monitor the interface with a logic analyzer. Compare the waveform with the waveform given in the datasheet for the device you are communicating with.
Check that the CSn is set correctly.
Check that the frame format is set correctly. Check if the device you are communicating with uses SPO = 1 or 0 and SPH = 1 or 0.
UART¶
Make sure to connect the TX pin of one device to the RX pin of the other device, and vice versa. If flow control is enabled, then the same applies towards the CTS and RTS pins.
Verify all communication settings between devices, including baud rate, data length, stop/parity bits and flow control.
Evaluate the interface with a logic analyzer or oscilloscope, using an analyzer tool if possible to convert the waveforms into their numerical counterpart.
Low Power Optimizations¶
If the device seems to be drawing too much current for your application, the following section will guide through the most common issues.
Note
Please refer to EnergyTrace User Guide as well as the Current Consumption Application Note for how to setup device for current consumption testing.
Check if the debugger is currently detached from the device. If using the XDS110 as debuger make sure to only connect the Ground and Power pins (this can be accomplished with jumper cables).

Figure 43. Modular LP EnergyTrace stand-alone Configuration¶
Warning
Confirm that the device has been power cycled since last time it was connected to the debugger.
Isolate the CC23xx from all peripheral devices (such as LEDS, External Flash, etc..) as these leakage currents might be the cause of higher power consumption than expected. If using a Launchpad confirm all jumpers are removed.
Isolate threads in the application until the thread with high power consumption is found. Once found, start isolating which peripherals (UART, I2C, SPI, ADC, Timers) are used in the thread and check if one of these could be the source of the issue. If any peripheral is set to start a transfer in blocking mode, the CC23xx will not be able to go into standby if the transfer never finished. Ex, if UART is set to restart receiving in blocking mode, the device will not go into standby until the expected data is received.
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 snippet below shows how to use DIO19 for 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;
// ...
}
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.

Figure 44. Power Policy Function in SysConfig¶
Note
The LF crystal clock is permanently enabled in standby mode.