class PIO – продвинутое использование PIO

Класс PIO оборачивает один из двух блоков программируемого ввода-вывода (PIO) микросхемы RP2040. Каждый блок PIO содержит память инструкций (32 инструкции), общую для четырёх независимых конечных автоматов, а также отдельный интерфейс FIFO к каждому конечному автомату и контроллер прерываний (IRQ).

Большинство скриптов взаимодействуют с PIO через StateMachine — этот класс предназначен для продвинутых сценариев, в которых требуется:

  • Явно загружать и удалять программы через add_program() / remove_program().

  • Перемещать базовый GPIO блока PIO в пределах 32-выводного окна микросхемы через gpio_base().

  • Подключаться к флагам IRQ на уровне всего блока через irq().

Об ассемблировании программ PIO см. rp2.asm_pio().

Конструкторы

class rp2.PIO(id: int)

Возвращает одиночный (singleton) объект PIO для блока PIO, заданного параметром id. У RP2040 два блока PIO с номерами 0 и 1. Для любого другого id вызывает ValueError.

Методы

gpio_base(base: machine.Pin | int | None = None, /) int

Получает или устанавливает базовый GPIO для этого блока PIO.

PIO микросхемы RP2040 видит 32-выводное окно в пространстве GPIO; окно может начинаться с GPIO0 или GPIO16. База определяет, какое окно действует для всех конечных автоматов на этом PIO.

Без аргумента возвращает текущую базу (номер вывода GPIO, 0 или 16).

С аргументом устанавливает базу. base может быть экземпляром machine.Pin или целочисленным номером вывода и должен соответствовать GPIO0 или GPIO16. Базу необходимо установить до добавления любой программы или создания конечного автомата на этом блоке PIO.

add_program(program: Callable) None

Загружает program в память инструкций этого PIO. Полученное размещение в памяти переиспользуется всеми конечными автоматами на этом блоке PIO.

Каждый PIO имеет всего 32 инструкции памяти программ, общей для всех программ; если новая программа не помещается, этот метод вызывает OSError(ENOMEM). Одну и ту же программу можно загрузить на оба экземпляра PIO, но они занимают отдельные области памяти.

remove_program(program: Callable | None = None, /) None

Удаляет program из памяти инструкций этого PIO, освобождая место для новых программ. Если program опущен, удаляются все программы, загруженные в данный момент на этот PIO.

Удаление программы, которая не была загружена, не приводит ни к каким действиям (без исключения).

state_machine(id: int, program: Callable | None = None, *args, **kwargs) StateMachine

Возвращает один из четырёх экземпляров StateMachine, принадлежащих этому блоку PIO. id — это локальный индекс конечного автомата (03).

Если задан program, конечный автомат настраивается на его выполнение — все позиционные/именованные аргументы передаются в StateMachine.init().

Пример:

>>> rp2.PIO(1).state_machine(3)
StateMachine(7)

Глобальный ID конечного автомата у возвращаемого объекта равен pio_id * 4 + sm_id.

irq(handler: Callable[[PIO], None] | None = None, trigger: int = IRQ_SM0 | IRQ_SM1 | IRQ_SM2 | IRQ_SM3, hard: bool = False) Callable

Получает или настраивает прерывание (IRQ) уровня блока для этого PIO.

handler — это функция обратного вызова, которая срабатывает при защёлкивании любого из запрошенных IRQ конечных автоматов. Обработчик получает этот экземпляр PIO в качестве единственного аргумента; внутри обработчика сработавшие конечные автоматы можно определить по self.irq().flags(), выполнив операцию И с константами IRQ_SM*.

trigger — это битовая маска одного или нескольких значений IRQ_SM0 .. IRQ_SM3. По умолчанию срабатывает на любом конечном автомате.

hard=True регистрирует обработчик аппаратного прерывания (без выделения памяти в куче внутри функции обратного вызова).

MicroPython привязывает IRQ 0 на каждом блоке PIO; IRQ 1 зарезервирован и недоступен из Python.

Константы

IN_LOW: int

Передайте в out_init / set_init / sideset_init функции asm_pio(), чтобы вывод начинал работу как вход с низким уровнем (то есть в высокоимпедансном состоянии с выходным буфером, удерживающим 0).

IN_HIGH: int

Передайте в out_init / set_init / sideset_init функции asm_pio(), чтобы вывод начинал работу как вход с выходным буфером, удерживающим 1.

OUT_LOW: int

Передайте в out_init / set_init / sideset_init функции asm_pio(), чтобы вывод начинал работу как активный выход с логическим уровнем 0.

OUT_HIGH: int

Передайте в out_init / set_init / sideset_init функции asm_pio(), чтобы вывод начинал работу как активный выход с логическим уровнем 1.

SHIFT_LEFT: int

Передайте в in_shiftdir / out_shiftdir функции asm_pio() или StateMachine.init(), чтобы сдвиги перемещали биты к старшему разряду (MSB).

SHIFT_RIGHT: int

Передайте в in_shiftdir / out_shiftdir функции asm_pio() или StateMachine.init(), чтобы сдвиги перемещали биты к младшему разряду (LSB).

JOIN_NONE: int

Передайте в fifo_join функции asm_pio(), чтобы у конечного автомата были отдельные 4-словные FIFO для передачи (TX) и приёма (RX) (значение по умолчанию).

JOIN_TX: int

Передайте в fifo_join функции asm_pio(), чтобы FIFO передачи (TX) удвоился до 8 слов, поглотив FIFO приёма (RX). Конечный автомат больше не может принимать данные.

JOIN_RX: int

Передайте в fifo_join функции asm_pio(), чтобы FIFO приёма (RX) удвоился до 8 слов, поглотив FIFO передачи (TX). Конечный автомат больше не может передавать данные.

IRQ_SM0: int

Флаг trigger метода irq(): конечный автомат 0 вызвал своё прерывание (IRQ).

IRQ_SM1: int

Флаг trigger метода irq(): конечный автомат 1 вызвал своё прерывание (IRQ).

IRQ_SM2: int

Флаг trigger метода irq(): конечный автомат 2 вызвал своё прерывание (IRQ).

IRQ_SM3: int

Флаг trigger метода irq(): конечный автомат 3 вызвал своё прерывание (IRQ).