I'm trying to use RP1 PIO to receive data from an IC with a non-standard interface, at a rate of approx. 750K words per second, translating to a bit more than 2MBytes/s of data.
I have a PIO program that works fine on an RP2350, but when running it on the RP1, the output of pio_sm_xfer_data falls apart after about 16 words.
I've read this thread about RP1 DMA speed:
viewtopic.php?t=390556
..but I think my problem is at the opposite side. The data returned by pio_sm_xfer_data is corrupted when the PIO produces at a slower rate than what the DMA can transfer.
I can reproduce the problem with this PIO program:and this C program to launch itWhen PIO clkdiv is set to 1.0, the output is continuously counting down. However, when clkdiv is set to 16.0, the output looks like this:My conclusion is, that something breaks when the RX FIFO is empty, or the pio_sm_xfer_data is invoked before a buffer is ready.
Is there a way for the consumer to pace the transfers? Or is this a bug in piolib?
I have a PIO program that works fine on an RP2350, but when running it on the RP1, the output of pio_sm_xfer_data falls apart after about 16 words.
I've read this thread about RP1 DMA speed:
viewtopic.php?t=390556
..but I think my problem is at the opposite side. The data returned by pio_sm_xfer_data is corrupted when the PIO produces at a slower rate than what the DMA can transfer.
I can reproduce the problem with this PIO program:
Code:
#pragma once#if !PICO_NO_HARDWARE#include "hardware/pio.h"#endif#define simple_wrap_target 0#define simple_wrap 4static const uint16_t simple_program_instructions[] = { // .wrap_target 0xe04a, // 0: set y, 10 0xa0c2, // 1: mov isr, y 0x8020, // 2: push block 0x0081, // 3: jmp y--, 1 0x0001, // 4: jmp 1 // .wrap};#if !PICO_NO_HARDWAREstatic const struct pio_program simple_program = { .instructions = simple_program_instructions, .length = 5, .origin = -1,};static inline pio_sm_config simple_program_get_default_config(uint offset) { pio_sm_config c = pio_get_default_sm_config(); sm_config_set_wrap(&c, offset + simple_wrap_target, offset + simple_wrap); return c;}static inline void simple_program_init(PIO pio, uint sm, uint offset) { pio_sm_config c = simple_program_get_default_config(offset); sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); sm_config_set_clkdiv(&c, 16.0); pio_sm_init(pio, sm, offset, &c); pio_sm_set_enabled(pio, sm, true);}#endifCode:
#include <stdio.h>#include "pico/stdlib.h"#include "hardware/pio.h"#include "simple.pio.h"#define BLOCK_SAMPLES 256#define BLOCK_SIZE_BYTES BLOCK_SAMPLES*4uint8_t data[BLOCK_SIZE_BYTES];int main() { PIO pio = pio0; uint sm = pio_claim_unused_sm(pio, true); uint offset = pio_add_program(pio, &simple_program); simple_program_init(pio, sm, offset); pio_sm_config_xfer(pio, sm, PIO_DIR_FROM_SM, BLOCK_SIZE_BYTES, 2); uint32_t* data_u32 = (uint32_t*) &data; pio_sm_xfer_data(pio, sm, PIO_DIR_FROM_SM, BLOCK_SIZE_BYTES, &data); for (int i = 0; i*4 < BLOCK_SAMPLES; i+=4) { printf("%08x %08x %08x %08x\n", data_u32[i], data_u32[i+1], data_u32[i+2], data_u32[i+3]); }}Code:
0000000a 00000009 00000008 0000000700000006 00000005 00000004 0000000300000002 00000001 00000000 fffffffffffffffe fffffffd fffffffc fffffffbfffffffa fffffff9 fffffff8 fffffff700000006 00000006 00000006 00000006fffffff6 fffffff5 00000004 0000000400000004 00000004 00000004 00000004fffffff4 fffffff3 00000002 0000000200000002 00000002 00000002 00000002fffffff2 fffffff1 00000000 0000000000000000 00000000 00000000 00000000fffffff0 ffffffef fffffffe fffffffefffffffe fffffffe fffffffe fffffffeffffffee fffffffd fffffffd ffffffedfffffffc fffffffc fffffffc fffffffcIs there a way for the consumer to pace the transfers? Or is this a bug in piolib?
Statistics: Posted by astuder — Wed Jan 07, 2026 8:12 am — Replies 3 — Views 52