RP2040-Zero battery connection

The RP2040-One would be ideal to remove VBUS. Solder USB-A cable to USB tabs, maybe ??

This is the post where I placed my experience of getting the Pico to sleep. Should work for the RP2040-One. You will need to keep the RTC clock going and maybe some others too. It’s possible this won’t work for your project. There may also be some changes to Micropython that make it easier.
It is python accessing the registers using assembler instructions. The RP2040 wakes on a GPIO pin.

This is the code I eventually used.

################################################################################
#
#			Pi Pico - Dormant function
#
#	Use these functions to put the Pico to sleep.
#	Power consumption drops to about 0.3mA.
#
# 	def dormant_until_pin(gpio_pin, edge=True, level=True):
#
#	gpio_pin - the GPIO pin interrupt that will wake the Pico
#	edge =  True  - triggers on an edge
#	edge =  False - triggers on a level
#	level = True  - rising edge or High level
#	level = False - falling edge or Low level
#
#   Created 10 Jan 2022
#  
#################################################################################
# Address & Register definitions
##############################################################################################
# GPIO Register start address, GPIO pin determines actual register
#    calculated by int(gpio / 8) * 4
IO_BANK0_BASE = 0x40014000
# Register offsets
IO_BANK0_INTR0 = 0x0f0
IO_BANK0_DORMANT_WAKE_INTE0 = 0x160
# Bit determines type of interrupt, 4 bits per register, 8 registers in each 32 bit word
#     Bit position for GPIO is calculated by event << 4 * (gpio % 8)
#         event is one of 4 options below
LEVEL_LOW =  0x00000001
LEVEL_HIGH = 0x00000002
EDGE_FALL =  0x00000004
EDGE_RISE =  0x00000008

# XOSC Register start address
XOSC_BASE = 0x40024000
XOSC_DORMANT = 0x08
XOSC_STATUS = 0x04
# Values to write to set dormant mode, wake value is set by default
XOSC_DORMANT_VALUE = 0x636f6d61
XOSC_WAKE_VALUE = 0x77616b65
# bit to check indicating XOSC is stable
XOSC_STATUS_STABLE_BIT = 0x80000000
# ROSC Registers start address
ROSC_BASE = 0x40060000

# Clock Registers start address
CLOCKS_BASE = 0x40008000
# Register offsets
CLK_REF_CTRL = 0x30
CLK_SYS_CTRL = 0x3C
CLK_PERI_CTRL = 0x48
CLK_USB_CTRL = 0x54
CLK_ADC_CTRL = 0x60
CLK_RTC_CTRL = 0x6C
PLL_SYS_BASE = 0x40028000
PLL_USB_BASE = 0x4002c000
PLL_PWR = 0x4

##############################################################################################
# Assember routines to directly access registers
##############################################################################################
@micropython.asm_thumb
def _read_bits(r0):
    ldr(r0, [r0, 0])

@micropython.asm_thumb
def _write_bits(r0, r1):
    str(r1, [r0, 0])

##############################################################################################
# Set dormant mode and activate
#     Found it better to put all the register manipulation in the same Python def()
##############################################################################################
def dormant_until_pin(gpio_pin, edge=True, level=True):
# convert edge and level to event
    if not edge and not level:
        event = LEVEL_LOW
    if not edge and level:
        event = LEVEL_HIGH
    if edge and not level:
        event = EDGE_FALL
    if edge and level:
        event = EDGE_RISE
#check for valid gpio
    if gpio_pin < 0 or gpio_pin > 27:
        raise RuntimeError("Invalid value for pin " + str(gpio_pin) + " (expect int between 0 and 27)")
# clear interrrupts
    _write_bits(IO_BANK0_BASE + IO_BANK0_INTR0 + int(gpio_pin / 8) * 4, event << 4 * (gpio_pin % 8))
# Enable Wake-up from GPIO IRQ
    _write_bits(IO_BANK0_BASE + IO_BANK0_DORMANT_WAKE_INTE0 + int(gpio_pin / 8) * 4, event << 4 * (gpio_pin % 8))
# Setup clocks for dormant
    _write_bits(CLOCKS_BASE + CLK_REF_CTRL, 0x02)
    _write_bits(CLOCKS_BASE + CLK_SYS_CTRL, 0x00)
    _write_bits(CLOCKS_BASE + CLK_USB_CTRL, 0x00)
    _write_bits(CLOCKS_BASE + CLK_ADC_CTRL, 0x00)
    _write_bits(CLOCKS_BASE + CLK_RTC_CTRL, 0x60)
    _write_bits(CLOCKS_BASE + CLK_PERI_CTRL, 0x00)
    _write_bits(PLL_USB_BASE + PLL_PWR, 0x2D)
    _write_bits(ROSC_BASE, 0xD1EAA0)
# go dormant
    _write_bits(XOSC_BASE + XOSC_DORMANT, XOSC_DORMANT_VALUE)
####################################
# execution stops here
####################################
# Normalise clocks
    _write_bits(CLOCKS_BASE + CLK_REF_CTRL, 0x02)
    _write_bits(CLOCKS_BASE + CLK_SYS_CTRL, 0x01)
    _write_bits(CLOCKS_BASE + CLK_USB_CTRL, 0x800)
    _write_bits(CLOCKS_BASE + CLK_ADC_CTRL, 0x800)
    _write_bits(CLOCKS_BASE + CLK_RTC_CTRL, 0x800)
    _write_bits(CLOCKS_BASE + CLK_PERI_CTRL, 0x800)
    _write_bits(PLL_USB_BASE + PLL_PWR, 0x04)
    _write_bits(ROSC_BASE, 0xfffaa0)
# Check for stable XOSC after wake up
    while not _read_bits(XOSC_BASE + XOSC_STATUS) & XOSC_STATUS_STABLE_BIT:
         pass
# clear interrupts
    _write_bits(IO_BANK0_BASE + IO_BANK0_INTR0 + int(gpio_pin / 8) * 4, event << 4 * (gpio_pin % 8))

#################################################################################

Regards
Jim

1 Like