Перейти к содержанию

Сколько данных помещается в FIFO PIO RP2040?

Обновлено Редакция GAW

Автомат PIO и процессор работают с разной скоростью и в разные моменты, поэтому между ними стоят FIFO. Если очередь пуста, команда PULL останавливает автомат; если переполнена — останавливается PUSH. Устройство очереди описано в термине «FIFO».

Варианты FIFO

НастройкаTX (система → автомат)RX (автомат → система)Когда нужно
По умолчанию4 слова4 словадвунаправленный обмен
PIO_FIFO_JOIN_TX8 словнетвывод: светодиоды, DPI, UART TX
PIO_FIFO_JOIN_RXнет8 словприём: логический анализатор, UART RX

Каждое слово — 32 бита. При объединении в одну сторону второе FIFO перестаёт работать: команда PUSH в объединённом на передачу автомате остановит его навсегда.

DMA

// Feed PIO0 SM0 TX FIFO from a buffer by DMA (RP2040 datasheet 2.5.3.1, 3.2.3.5)
dma_channel_config d = dma_channel_get_default_config(chan);
channel_config_set_dreq(&d, pio_get_dreq(pio0, 0, true));   // DREQ_PIO0_TX0
dma_channel_configure(chan, &d, &pio0->txf[0], buf, count, true);

Каждый FIFO выдаёт свой запрос DREQ: у PIO0 это номера 0–3 для TX и 4–7 для RX, у PIO1 — 8–15. DMA пишет слово, как только в очереди появляется место, и процессор в передаче не участвует (термин «DMA»). Если передавать нужно не 32-битные слова, порог autopull задают по ширине данных — тогда регистр сдвига перезагружается сам.

Как сделать, чтобы автомат одновременно выдавал данные и тактовый сигнал, разобрано в ответе «Что такое side-set в PIO», частоту автомата считает калькулятор PIO RP2040. Набор команд и примеры — на странице PIO RP2040.

Похожие вопросы

Почему после sm_config_set_fifo_join потерялись данные?

По даташиту смена FJOIN отбрасывает всё, что было в FIFO этого автомата. Объединение настраивают до запуска автомата, а если данные уже есть, их сначала вычитывают.

Хватит ли процессора, чтобы кормить PIO без DMA?

Для медленных интерфейсов — да, но FIFO на 4 слова опустеет за несколько тактов автомата, если он выдаёт по слову за такт. Даташит указывает, что FIFO на 8 элементов достаточно для передачи одного слова за такт через DMA, — это и есть основной способ для потоковых интерфейсов.

Чем autopull лучше команды PULL?

Автомат сам загружает новое слово в регистр сдвига OSR, когда сдвинуто заданное число бит, — в программе не нужна отдельная команда PULL и цикл подсчёта битов. Это экономит команды в 32-командной памяти и такты.

Источники

  1. Raspberry Pi Ltd. RP2040 Datasheet (build 2025-02-20) — разд. 3.2.3.5: у каждого автомата пара FIFO по 4 слова — TX (запись системой, процессором или DMA) и RX (запись автоматом); FIFO выдают сигналы DREQ для DMA; SHIFTCTRL_FJOIN объединяет их в одно FIFO на 8 элементов в одну сторону; разд. 3.2.4: блокирующий PULL при пустом TX и PUSH при полном RX останавливают автомат; разд. 3.5.3: при объединении второе FIFO недоступно (PUSH остановится, в FSTAT оно одновременно полное и пустое), смена FJOIN теряет данные в FIFO; 8 элементов достаточно для одного слова за такт через DMA, если DMA не тормозят другие ведущие; UART с 8-словным FIFO может ждать прерывания вдвое дольше; разд. 3.5.4: autopush и autopull по порогам PUSH_THRESH и PULL_THRESH; разд. 2.5.3.1, системная таблица DREQ: DREQ_PIO0_TX0…TX3 = 0–3, DREQ_PIO0_RX0…RX3 = 4–7, PIO1 — 8–15
  2. Raspberry Pi Ltd. pico-sdk 2.3.1, src/rp2_common/hardware_pio/include/hardware/pio.h — sm_config_set_fifo_join(c, join): PIO_FIFO_JOIN_TX — TX на 8 слов, RX выключен, PIO_FIFO_JOIN_RX — наоборот (варианты TXGET, TXPUT, PUTGET — только для RP2350); sm_config_set_in_shift(c, shift_right, autopush, push_threshold); sm_config_set_out_shift(c, shift_right, autopull, pull_threshold); pio_get_dreq(pio, sm, is_tx) — номер DREQ автомата
  3. Raspberry Pi Ltd. pico-sdk 2.3.1, src/rp2_common/hardware_dma/include/hardware/dma.h — dma_channel_get_default_config(channel), channel_config_set_dreq(c, dreq), dma_channel_configure(channel, config, write_addr, read_addr, transfer_count, trigger)

Нашли ошибку?