клас 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.