Hi Tim
Thanks for your purchase!
You can definitely disable the RP2040. It’s done half in hardware and half in software.
Hardware:
There is a load switch that controls VDDIO. This can be activated either by plugging in VBUS or bringing the VDDIO_EN signal high. This is connected to the GPIO0 pin on the PMIC.

Software
In the 2.7.x branch of NFED, the active_sleep outlines how to turn of the VCC (BUCK2 on the nPM1300)
The big thing is to enable regulator control in your boards/circuitdojo_feather_nrf9151_ns.conf
:
# Regulator control
CONFIG_REGULATOR=y
CONFIG_REGULATOR_NPM1300=y
Then in your code:
#include <zephyr/drivers/mfd/npm1300.h>
#include <zephyr/drivers/regulator.h>
/* Addresses */
#define NPM1300_BUCK_BASE 0x04U
#define NPM1300_BUCK_OFFSET_EN_CLR 0x01U
#define NPM1300_BUCK_BUCKCTRL0 0x15U
#define NPM1300_BUCK_STATUS 0x34U
/* Bits */
#define NPM1300_BUCK2_MODE_BIT BIT(0)
#define NPM1300_BUCK2_PULLDOWN_EN BIT(3)
static const struct device *buck2 = DEVICE_DT_GET(DT_NODELABEL(npm1300_buck2))
static int setup_pmic()
{
#if defined(CONFIG_BOARD_CIRCUITDOJO_FEATHER_NRF9161) || defined(CONFIG_BOARD_CIRCUITDOJO_FEATHER_NRF9151)
int err;
/* Get pmic */
static const struct device *pmic = DEVICE_DT_GET(DT_NODELABEL(npm1300_pmic));
if (!pmic)
{
LOG_ERR("Failed to get PMIC device\n");
return -ENODEV;
}
/* Disable if not already disabled */
if (regulator_is_enabled(buck2))
{
err = regulator_disable(buck2);
if (err < 0)
{
LOG_ERR("Failed to disable buck2: %d", err);
return err;
}
}
uint8_t reg = 0;
/* See if pulldown is not already enabled */
err = mfd_npm1300_reg_read(pmic, NPM1300_BUCK_BASE, NPM1300_BUCK_BUCKCTRL0,
®);
if (err < 0)
LOG_ERR("Failed to set VBUSINLIM. Err: %d", err);
if ((reg & (NPM1300_BUCK2_PULLDOWN_EN)) == 0)
{
/* Write to MFD to enable pulldown for BUCK2 */
err = mfd_npm1300_reg_write(pmic, NPM1300_BUCK_BASE, NPM1300_BUCK_BUCKCTRL0,
NPM1300_BUCK2_PULLDOWN_EN);
if (err < 0)
LOG_ERR("Failed to set VBUSINLIM. Err: %d", err);
}
#endif
return 0;
}
You can call the setup_pmic()
function where ever it’s safe to do so for I2C transaction (I suggest keeping all I2C operations on one thread).
This will disable the BUCK and enable the pull-down to make sure VCC isn’t floating around causing issues.
I’m going to work on a reference that will dynamically power the RP2040 so you don’t have to invoke any of this yourself. Stay tuned on that.
@AchimKraus did test out the USB detect interrupt and it does work so half the work is already done. 😃
One final thing I would recommend you do in the firmware: add a 2 second delay in your app before you invoke the buck2 power down function. That way you can still halt/reset/program the board. If you do it too quickly, it can be a bit tricky to get it back to a happy state. As far as I remember if you hold reset while plugging in USB and then immediately program your code of choice should un-stick it. (Never-mind on this suggestion, I built it into the nfed/boards/circuitdojo/feather_nrf9151/startup.c
file a while ago as I foresaw this being an issue. Therefore, adding an extra delay, while it doesn’t hurt, isn’t necessary.)
I hope that helps get you started.
P.S. if you load up the active_sleep
sample you should get < 10uA sleep. Last time I measured a couple boards it was more like 5uA at room temp.