8000 rp2pio.StateMachine.background_read() behavior confusing · Issue #10384 · adafruit/circuitpython · GitHub
[go: up one dir, main page]

Skip to content
8000
rp2pio.StateMachine.background_read() behavior confusing #10384
Open
@ambv

Description

@ambv

CircuitPython version and board name

CircuitPython main at 116b29b65789dc8c10802b0f5cbb8b4130b07197 (May 27th, post 10.0 alpha 6) on RP2040.

Code/REPL

Adafruit CircuitPython 10.0.0-alpha.6-9-gaf95f3c82a-dirty on 2025-05-28; denki-oto rin with rp2040
>>> import board, rp2pio, adafruit_pioasm
>>> rx = board.RXPIN0
>>> bits = 8
>>> baudrate = 100000
>>> program = adafruit_pioasm.Program(
...     ".program uart_rx_mini\n"
...     ".fifo auto\n"
...     "start:\n"
...     "  wait 0 pin 0\n"
...     f"  set x, {bits - 1} [10]\n"
...     "bitloop:\n"
...     "  in pins, 1\n"
...     "  jmp x-- bitloop [6]\n"
...     "  jmp pin good_stop\n"
...     "  wait 1 pin 0\n"
...     "  jmp start\n"
...     "good_stop:\n"
...     "  push\n"
... )
>>>
>>> pio = rp2pio.StateMachine(
...     program.assembled,
...     first_in_pin=rx,
...     jmp_pin=rx,
...     frequency=8 * baudrate,
...     auto_push=False,
...     push_threshold=bits,
...     **program.pio_kwargs,
... )
>>>
>>> pio.reading  # <-- that's a bug
True
>>> pio.pending_read
0
>>> buf1 = bytearray([255] * 25)
>>> buf1
bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff')
>>> pio.background_read(buf1)
>>> pio.reading
True
>>> pio.pending_read
1
>>> while pio.pending_read:
..
6C49
.     print(end=".")
................
>>> buf1  # <-- the buffer filled with zeroes instead of actual data
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
>>> pio.reading
False
>>> pio.pending_read
0
>>> pio.readinto(buf1)
>>> buf1  # <-- that's actual data, `pio.readinto()` works correctly
bytearray(b'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x0f\x01\x01\x01\x01\x01\x01\x01\x01\x03')
>>>

Behavior

There's multiple problems here.

According to the docs, StateMachine.reading should only be True when a background_read is in progress. This is a minor bug in itself as the dma_completed_read bool is never initialized in StateMachine.c:rp2pio_statemachine_construct().

More importantly, I don't understand how I'm supposed to use this. The documentation says of the WriteableBuffer arguments that they will be "read", once or in a loop. This language is confusing as those arguments are clearly to be written to in the background. But the larger problem is that it's entirely unclear how user code is supposed to read those buffers and when. How do I know when the buffer has data and how much has been written to it already? How do I keep reading it so that it doesn't overflow?

There doesn't seem to be any event other than polling StateMachine.reading or StateMachine.pending_read.

What's more, the result of such a background_read(buf) is that the buffer is filled with zeroes and not the data PIO received. This is easily proven by using readinto(buf), which works correctly.

Finally, the documentation states that consecutive calls to background_read(buf) while another read is pending should stack up and block. This is not the case. In fact, currently a call to background_read() while a DMA read was already in progress resets everything immediately. pending_read goes to 0 instead to 2.

It is entirely possible that I'm simply very confused and I can't use this functionality correctly. Please advise.

Description

No response

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugrp2Both RP2 microcontrollers

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0