клас I2CTarget – цільовий пристрій I2C

Цільовий пристрій I2C – це пристрій, який підключається до шини 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()

Зверніть увагу, що деякі порти вимагають передачі id, а можливо, також виводів scl та sda, конструктору I2CTarget для вибору апаратного екземпляра 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_*, об’єднаних операцією АБО; за замовчуванням спрацьовує після завершення кожного читання або запису на стороні контролера.

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_* є бітовим прапором. Об’єднайте їх операцією АБО для побудови маски 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.