← index #15814Issue #17509
Off-topic · high · value 1.095
QUERY · ISSUE

Raspberry Pi Pico ADC changes the sampling rate in Free-running Sampling mode

openby leezishengopened 2024-09-09updated 2024-09-11
bug

Port, board and/or hardware

Raspberry Pi Pico

MicroPython version

MicroPython v1.23.0 ,RPI_PICO-20240602-v1.23.0

Reproduction

def configure_adc_sample_rate(self, sample_rate):
    """
    Configure the ADC sampling rate. Due to unknown reasons, the DIV register cannot be configured here. The actual sampling period is fixed at 65
    :param sample_rate: Desired sample rate (Hz)
    :return: None
    """
    # Ensure that the sampling rate is within a reasonable range
    if sample_rate <= 0 or sample_rate > 48_000_000:
        raise ValueError("sample rate out of range")

    # Calculate divider value
    total_period = 48_000_000 / sample_rate
    int_part = int(total_period) - 1
    frac_part = int((total_period - int_part - 1) * 256)
    div_value = mem32[DMA_ADC_Transfer.DIV_REG]

    
    # Write the sampling period to the DIV register
    mem32[DMA_ADC_Transfer.DIV_REG] = div_value | (int_part << 8) | frac_part

Expected behaviour

I am configuring the ADC sampling rate here. Due to unknown reasons, the DIV register cannot be configured here. The actual sampling period is fixed at 65.
Can anyone help me what is going wrong here?

Observed behaviour

(base) PS D:\lee\windows terminal\terminal-1.17.11461.0> mpremote connect COM8
Connected to MicroPython at COM8
Use Ctrl-] or Ctrl-x to exit this shell

div_value = mem32[DMA_ADC_Transfer.DIV_REG]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'mem32' isn't defined
from machine import mem32
div_value = mem32[DMA_ADC_Transfer.DIV_REG]
div_value
12582656
total_period = 48_000_000 / 48000
total_period = 48_000_000 / 480000
total_period
100.0
int_part = int(total_period) - 1
frac_part = int((total_period - int_part - 1) * 256)
mem32[DMA_ADC_Transfer.DIV_REG] = div_value | (int_part << 8) | frac_part
mem32[DMA_ADC_Transfer.DIV_REG]
12582656
total_period = 48_000_000 / 480000
int_part = int(total_period) - 1
frac_part = int((total_period - int_part - 1) * 256)
mem32[DMA_ADC_Transfer.DIV_REG] = div_value | (int_part << 8) | frac_part
mem32[DMA_ADC_Transfer.DIV_REG]
12582656

Additional Information

<img width="554" alt="a91a38f1944c012e122d14c44dcbc40" src="https://github.com/user-attachments/assets/bf2fc3ad-9186-4a46-82b2-0262dbcb828a">

Code of Conduct

Yes, I agree

CANDIDATE · ISSUE

RP2350: PIO2 State Machines do not work

closedby IntergalacticMicrosystemsopened 2025-06-17updated 2025-08-01
bugport-rp2

Port, board and/or hardware

ports-rp2 Pico 2

MicroPython version

MicroPython v1.26.0-preview.251.g5ade8b705 on 2025-06-16; Raspberry Pi Pico2 with RP2350

Reproduction

pio_1hz.py from examples does not blink the LED or trigger the interrupt when switched to StateMachine IDs 8, 9, 10, or 11.

Expected behaviour

No response

Observed behaviour

What I've found so far:
PIO2_BASE + SM0_EXECCTRL is set incorrectly
PIO2 instruction memory is not loaded
Instruction start address is not set

Additional Information

This code mostly works.
The IRQ handler only triggers once, not repeatedly as expected.

import time
from machine import Pin
import rp2

@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def blink_1hz():
    # fmt: off
    # Cycles: 1 + 1 + 6 + 32 * (30 + 1) = 1000
    irq(rel(0))
    set(pins, 1)
    set(x, 31)                  [5]
    label("delay_high")
    nop()                       [29]
    jmp(x_dec, "delay_high")

    # Cycles: 1 + 1 + 6 + 32 * (30 + 1) = 1000
    nop()
    set(pins, 0)
    set(x, 31)                  [5]
    label("delay_low")
    nop()                       [29]
    jmp(x_dec, "delay_low")
    # fmt: on


# Create the StateMachine with the blink_1hz program, outputting on Pin(25).
sm = rp2.StateMachine(8, blink_1hz, freq=2300, set_base=Pin(25))

# Set the IRQ handler to print the millisecond timestamp.
sm.irq(lambda p: print(time.ticks_ms()))

# -------- MANUAL REGISTER SETTING START -----------
import machine
PIO2_BASE = 0x50400000
SM0_EXECCTRL = 0xCC
INSTR_MEM0 = 0x48
SM0_INSTR = 0xD8
machine.mem32[PIO2_BASE + SM0_EXECCTRL] = 129920
instrs = [49168, 57345, 58687, 48450, 89, 41026, 57344, 58687, 48450, 94]
instr_start = 0x48 + (4 * (32-len(instrs)))
for idx,instr in enumerate(instrs):    
    machine.mem32[PIO2_BASE + instr_start + (idx*4)] = instr
machine.mem32[PIO2_BASE + SM0_INSTR]=32-len(instrs)
# -------- MANUAL REGISTER SETTING END -----------

# Start the StateMachine.
sm.active(1)

while(True):
    pass

Code of Conduct

Yes, I agree

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied