TI CC2340 Power Optimization: From Active Mode to Standby

Your CC2340 BLE peripheral works on the bench. It advertises, connects, sends data. And it’s pulling 3x the current the datasheet promised. The coin cell budget that looked comfortable on the spreadsheet is now a 6-month battery life instead of 3 years.
The CC2340 can hit those datasheet numbers. The silicon isn’t lying. But the power policy manager, the piece of firmware that’s supposed to drop your chip into standby between connection events, only works when nothing is standing in its way. And in a typical first-pass BLE project, a half-dozen things are blocking it. Most of them are invisible unless you know where to look.
This guide is the systematic walkthrough for getting your CC2340 power consumption from “prototype” to “ships on a coin cell.” It covers BLE peripheral applications specifically and assumes you’ve already got a project compiling in the SimpleLink SDK.
CC2340 Power Modes and What Controls Them
Four modes matter for the CC2340:
+------------------------------------------------------------------+
| CC2340 Power Mode Hierarchy |
+------------------------------------------------------------------+
| |
| Active ──► Idle ──► Standby ──► Shutdown |
| (CPU + (CPU off, (Most clocks (RAM lost, |
| Radio) periph on) off, RAM wakeup via |
| retained) GPIO/reset) |
| |
| ◄── Increasing power savings / Increasing wake latency ──► |
| |
| Power Policy Manager handles transitions automatically |
| IF no active constraints prevent deeper sleep. |
+------------------------------------------------------------------+Active is where the CPU runs code and the radio transmits or receives. Idle parks the CPU but keeps peripherals clocked. Standby shuts down most clocks while retaining RAM; this is where your BLE peripheral should live for 99%+ of its time. Shutdown drops everything, including RAM, and is a separate topic.
You don’t manually call “enter standby.” The power policy manager makes that decision every time the RTOS idle task runs. Your firmware’s job is to make sure nothing prevents it from choosing standby.
For a BLE peripheral, the goal is simple: wake up, handle the connection event (or send an advertisement), then get back to standby as fast as possible.
The Power Policy Manager: What Blocks It
TI’s SimpleLink SDK uses a constraint-based power system. Drivers and modules declare power constraints when they need certain resources. The power policy manager checks those constraints before each sleep decision. If any constraint is active, it won’t enter the corresponding deeper state.
You can audit active constraints through the Power module APIs. Power_getConstraintMask() returns a bitmask of everything currently preventing deeper sleep. If you call this right before your application goes idle and see constraints you don’t expect, that’s your smoking gun.
Common constraint holders: UART driver (holds a constraint while open), SPI driver (during transactions), ADC (while sampling), and the BLE stack itself (during radio events, which is expected). The unexpected ones are where your power budget leaks.
BLE Stack Configuration for CC2340 Low Power
The radio is your biggest power consumer, and BLE stack settings are your biggest levers.
Connection interval is the single most impactful parameter. A 7.5ms connection interval means the radio wakes 133 times per second. A 500ms interval means twice per second. That’s roughly a 60x difference in radio duty cycle. For a sensor that reports every few seconds, start at 200ms or higher and tune from there. Your phone’s BLE stack will negotiate, but set your preferred range aggressively in the GAP parameters.
Advertising interval follows the same logic. The default 100ms advertising interval is great for fast discovery, terrible for battery. For asset tags or sensors, 1s or even 2s intervals are common. If discovery time matters, consider starting with a fast interval (200ms for the first 30 seconds) then stepping down to something slower.
Slave latency is an underused tool. It lets your peripheral skip connection events when it has nothing to send. With a slave latency of 4 and a 100ms connection interval, your peripheral effectively sleeps for 500ms between radio wakes. It’s still reachable within 100ms when the central has data. For sensor peripherals, push this number up.
TX power defaults vary by project template. Don’t transmit at 5 dBm when 0 dBm gets the range you need. Measure your actual required link budget and dial it back.
BLE 5 features on the CC2340 help too. Coded PHY (S=8) gives you roughly 4x the range at the same TX power, or the same range at lower TX power. Extended advertising lets you pack more data per advertisement, reducing how often you need to advertise.
Firmware Patterns That Kill Standby
This is where most of the CC2340 power consumption mystery gets solved. These patterns are individually small but collectively devastating to your battery life.
UART drivers left open. TI’s driver framework holds a power constraint while a UART handle is open. If you opened UART for a debug print during init and never closed it, the power policy manager can’t enter standby. Close UART handles after use, or switch to callback mode where the driver releases its constraint between transactions.
Floating GPIOs. An unconnected input pin without a pull resistor can oscillate and draw microamps continuously. Every unused GPIO should be configured as output-low or input with an internal pull. Audit every pin in SysConfig.
Short-interval timers. A 10ms periodic timer means the CPU wakes 100 times per second, even if the callback does almost nothing. Each wake has fixed overhead: clock startup, context restore, settling time. If you’re reading a sensor every 10ms, ask whether you really need that rate, or if 1s would work. The difference in average current is enormous.
Polling sensors instead of using interrupts. If your accelerometer has an INT pin (and almost all of them do), use it. Wire it to a GPIO, configure a wakeup interrupt, and let the sensor tell you when something interesting happened. Polling means the CPU stays active or wakes on a timer. Interrupt-driven design means the CPU sleeps until the sensor says otherwise.
Debug interfaces left active. JTAG/SWD keeps clocks running. Your production build needs to either disable the debug port or configure those pins for normal GPIO operation.
Serial logging is the single most common reason a prototype draws 10x its expected current. UART-based printf debugging keeps the driver open and the chip out of standby. Compile it out for release builds. Use preprocessor guards; don’t rely on “I’ll remember to remove those later.”
+----------------------------------------------+
| Common Power Traps: Quick Checklist |
+----------------------------------------------+
| [ ] All unused GPIOs configured properly |
| [ ] UART driver closed when not in use |
| [ ] SPI/I2C transactions are burst + close |
| [ ] No short-interval periodic timers |
| [ ] Sensors using interrupt, not polling |
| [ ] Debug/logging disabled in release build |
| [ ] JTAG pins configured for production |
+----------------------------------------------+SysConfig and SimpleLink SDK Power Settings
SysConfig is where several critical power decisions live.
Power Policy: Make sure it’s enabled and set to the default (aggressive) policy. In SysConfig, under TI Drivers > Power, confirm the policy function is set and not overridden to a custom stub.
Unused peripherals: If your design doesn’t use the ADC, the TRNG, or a particular timer, disable them entirely in SysConfig. Each enabled peripheral module may hold clocks or resources that have power implications even when idle.
Clock source selection: For standby timekeeping, you’ll choose between LFOSC (internal) and LFXTAL (external 32.768 kHz crystal). LFOSC burns slightly less current but is less accurate, which can affect BLE connection timing and lead to more radio wake-ups for resynchronization. If you’re pushing for long connection intervals or aggressive slave latency, the LFXTAL tends to pay for itself.
DMA usage: For any peripheral I/O (SPI reads from a sensor, ADC sampling), use DMA transfers. The CPU can sleep while DMA handles the data movement, then wake only to process the result. This is especially impactful for burst reads from sensors over SPI.
If your application needs a custom power policy (for instance, forcing shutdown after a long idle period), the Power_setPolicy() API lets you install your own. But for most BLE peripherals, the default policy does the right thing once you’ve cleared the constraints.
Validating Your Power Profile
You need a way to see what your chip is doing between connection events. Two practical options:
EnergyTrace (if you have a TI LaunchPad with EnergyTrace support) gives you a real-time current profile inside Code Composer Studio. It’s not lab-grade precise, but it shows the shape of your power profile clearly: you’ll see spikes for radio events, a baseline between them, and (hopefully) that baseline sitting at standby-level current.
Current sense amplifier plus a scope is the higher-fidelity option. A 10-ohm shunt resistor in series with the supply, probed with a differential amp, gives you a time-domain view of exactly what’s happening. Look for the sleep/wake pattern across a full connection interval.
What you’re looking for: clean standby current between connection events, with no unexpected bumps or elevated baseline. If you see the baseline sitting at hundreds of microamps instead of single-digit microamps, something is preventing standby. Go back to Power_getConstraintMask() and work through the checklist above.
Don’t obsess over peak current during radio events. Those are short, determined by TX power and PHY settings, and largely fixed. A 4mA peak for 1ms every 500ms is trivial. A 200µA average because you forgot to close the UART handle is a battery killer.
If you’re building a device that reports through Hubble’s network, the TI CC2340 FreeRTOS reference application is a good starting point, as it already incorporates many of these patterns. For understanding how the advertising packet itself is structured, the advertising packet documentation covers the payload format.
Closing the Gap Between Datasheet and Bench
The CC2340 is capable of excellent standby current for BLE peripherals. The gap between datasheet numbers and your bench measurements almost always comes down to firmware, not silicon.
Start with the big levers: connection interval, advertising interval, slave latency. Then hunt down the traps: open drivers, floating pins, chatty timers, debug leftovers. Verify with actual current measurement, not assumptions. Clear the constraints blocking the power policy manager, and your coin cell budget starts making sense.
Hubble Network enables BLE devices like the CC2340 to transmit data directly to satellites—no gateways, no infrastructure. See how it works →