Description
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