class I2CTarget – целевое устройство I2C¶
Целевое устройство I2C (target) – это устройство, которое подключается к шине I2C и управляется контроллером I2C. Целевые устройства I2C могут принимать различные формы. Класс machine.I2CTarget реализует целевое устройство I2C, которое может быть настроено как устройство памяти/регистров или как произвольное устройство I2C с использованием функций обратного вызова (если поддерживается портом).
Доступно на OpenMV Cam M4 / M7 / H7 / H7 Plus / Pure Thermal / RT1062 / AE3.
Пример использования для случая устройства памяти:
from machine import I2CTarget
# Create the backing memory for the I2C target.
mem = bytearray(8)
# Create an I2C target. Depending on the port, extra parameters
# may be required to select the peripheral and/or pins to use.
i2c = I2CTarget(addr=67, mem=mem)
# At this point an I2C controller can read and write `mem`.
...
# Deinitialise the I2C target.
i2c.deinit()
Обратите внимание, что некоторые порты требуют передачи в конструктор I2CTarget параметра id, а возможно, и выводов scl и sda, чтобы выбрать аппаратный экземпляр I2C и выводы, к которым он подключён.
При настройке в качестве устройства памяти также возможна регистрация для получения событий. Например, чтобы получать уведомления о чтении/записи памяти:
from machine import I2CTarget
# Define an IRQ handler, for I2C events.
def irq_handler(i2c_target):
flags = i2c_target.irq().flags()
if flags & I2CTarget.IRQ_END_READ:
print("controller read target at addr", i2c_target.memaddr)
if flags & I2CTarget.IRQ_END_WRITE:
print("controller wrote target at addr", i2c_target.memaddr)
# Create the I2C target and register to receive default events.
mem = bytearray(8)
i2c = I2CTarget(addr=67, mem=mem)
i2c.irq(irq_handler)
Более сложные устройства I2C можно реализовать, используя полный набор событий. Например, чтобы увидеть необработанные события по мере их возникновения:
from machine import I2CTarget
# Define an IRQ handler that prints the event id and responds to reads/writes.
def irq_handler(i2c_target, buf=bytearray(1)):
flags = i2c_target.irq().flags()
print(flags)
if flags & I2CTarget.IRQ_READ_REQ:
i2c_target.write(buf)
if flags & I2CTarget.IRQ_WRITE_REQ:
i2c_target.readinto(buf)
# Create the I2C target and register to receive all events.
i2c = I2CTarget(addr=67)
all_triggers = (
I2CTarget.IRQ_ADDR_MATCH_READ
| I2CTarget.IRQ_ADDR_MATCH_WRITE
| I2CTarget.IRQ_READ_REQ
| I2CTarget.IRQ_WRITE_REQ
| I2CTarget.IRQ_END_READ
| I2CTarget.IRQ_END_WRITE
)
i2c.irq(irq_handler, trigger=all_triggers, hard=True)
Конструкторы¶
- class machine.I2CTarget(id: int, addr: int, *, addrsize: int = 7, mem: bytearray | None = None, mem_addrsize: int = 8, scl: Pin | None = None, sda: Pin | None = None)¶
Создаёт и возвращает новый объект I2CTarget, используя следующие параметры:
id идентифицирует конкретное периферийное устройство I2C. Допустимые значения зависят от конкретного порта/платы. У некоторых портов есть значение по умолчанию, и в этом случае данный параметр можно опустить.
addr – это адрес I2C целевого устройства.
addrsize – это количество бит в адресе целевого устройства I2C. Допустимые значения – 7 и 10.
mem – это объект с буферным протоколом, доступный для записи. Если не указан, то резервная память отсутствует, и данные должны читаться/записываться с помощью методов
I2CTarget.readinto()иI2CTarget.write().mem_addrsize – это количество бит в адресе памяти. Допустимые значения – 0, 8, 16, 24 и 32.
scl – это объект вывода, указывающий вывод для использования в качестве SCL.
sda – это объект вывода, указывающий вывод для использования в качестве SDA.
Обратите внимание, что некоторые порты/платы имеют значения scl и sda по умолчанию, которые можно изменить в этом конструкторе. У других значения scl и sda фиксированы и не могут быть изменены.
Общие методы¶
- deinit() None¶
Деинициализирует целевое устройство I2C. После вызова этого метода аппаратура перестанет отвечать на запросы на шине I2C, и никакие другие методы вызвать нельзя.
- readinto(buf: bytearray) int¶
Читает в заданный буфер любые ожидающие байты, записанные контроллером I2C. Возвращает количество прочитанных байтов.
- write(buf: bytes) int¶
Выводит байты из заданного буфера, чтобы передать их контроллеру I2C после того, как он отправит запрос на чтение. Возвращает количество записанных байтов. Большинство портов принимают этому методу только по одному байту за раз.
- irq(handler: Callable[[I2CTarget], None] | None = None, trigger: int = IRQ_END_READ | IRQ_END_WRITE, hard: bool = False) None¶
Устанавливает обработчик прерывания
handler, который вызывается при срабатывании одного из событий, выбранных параметромtrigger.trigger– это битовая маска константIRQ_*, объединённых через OR; по умолчанию срабатывает в конце каждого чтения или записи со стороны контроллера.hard=Trueрегистрирует обработчик аппаратного прерывания (без выделения памяти в куче внутри функции обратного вызова). По умолчанию используется запланированная функция обратного вызова. Передайтеhandler=None, чтобы отключить прерывание.Примечание
IRQ_ADDR_MATCH_READ,IRQ_ADDR_MATCH_WRITE,IRQ_READ_REQиIRQ_WRITE_REQдолжны обрабатываться функцией обратного вызова аппаратного прерывания (hard=True), поскольку эти события необходимо подтверждать синхронно с аппаратурой.IRQ_END_READиIRQ_END_WRITEмогут обрабатываться как мягкими, так и аппаратными функциями обратного вызова; все события используют один общий обработчик, поэтому если хотя бы одному событию нужна аппаратная функция обратного вызова, то она нужна им всем.Когда в конструктор передан буфер памяти, драйвер подавляет
IRQ_END_WRITEдля транзакции, которая лишь записывает адрес памяти. Это сохраняет осмысленность событий окончания транзакции даже тогда, когда планировщик мягких прерываний откладывает функцию обратного вызова.
- memaddr¶
Целочисленное значение последнего адреса памяти, выбранного контроллером I2C (действительно только если в конструкторе был указан
mem).
Константы¶
Каждая константа
IRQ_*представляет собой флаговый бит. Объединяйте их через OR для построения маскиtriggerдляirq(). Внутри обработчика набор сработавших событий можно восстановить черезself.irq().flags(), применив AND с каждой константой.- IRQ_ADDR_MATCH_READ: int¶
Срабатывает, когда контроллер адресует это целевое устройство для транзакции чтения (байт адреса получен с битом чтения/записи, установленным в
1). Только аппаратное прерывание.
- IRQ_ADDR_MATCH_WRITE: int¶
Срабатывает, когда контроллер адресует это целевое устройство для транзакции записи (байт адреса получен с битом чтения/записи, установленным в
0). Только аппаратное прерывание.
- IRQ_READ_REQ: int¶
Срабатывает, когда контроллер запрашивает байт у целевого устройства. Обработчик должен вызвать
write(), чтобы предоставить байт до завершения тактового цикла контроллера. Только аппаратное прерывание.
- IRQ_WRITE_REQ: int¶
Срабатывает, когда контроллер передал байт в целевое устройство. Обработчик должен вызвать
readinto(), чтобы получить байт до того, как контроллер отправит следующий. Только аппаратное прерывание.
- IRQ_END_READ: int¶
Срабатывает, когда контроллер завершил транзакцию чтения (получен STOP / повторный START). Может обрабатываться как аппаратной, так и мягкой функцией обратного вызова прерывания.
- IRQ_END_WRITE: int¶
Срабатывает, когда контроллер завершил транзакцию записи (получен STOP / повторный START). Может обрабатываться как аппаратной, так и мягкой функцией обратного вызова прерывания. Подавляется для транзакции, которая записывает адрес памяти, когда в конструктор был передан буфер
mem.