třída I2CTarget – cílové zařízení I2C

I2C target je zařízení, které se připojuje ke sběrnici I2C a je řízeno I2C řadičem. I2C targety mohou mít mnoho podob. Třída machine.I2CTarget implementuje I2C target, který lze nakonfigurovat jako paměťové/registrové zařízení, nebo jako libovolné I2C zařízení pomocí callbacků (pokud to port podporuje).

Dostupné na OpenMV Cam M4 / M7 / H7 / H7 Plus / Pure Thermal / RT1062 / AE3.

Příklad použití pro případ paměťového zařízení:

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()

Pamatujte, že některé porty vyžadují předání id a případně pinů scl a sda konstruktoru I2CTarget pro výběr hardwarové instance I2C a pinů, ke kterým se připojuje.

Když je nakonfigurován jako paměťové zařízení, je také možné se registrovat pro příjem událostí. Například pro upozornění, když je paměť čtena/zapsána:

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)

Složitější I2C zařízení lze implementovat pomocí plné sady událostí. Například pro zobrazení surových událostí ve chvíli, kdy jsou spouštěny:

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)

Konstruktory

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)

Vytvoří a vrátí nový objekt I2CTarget s použitím následujících parametrů:

  • id identifikuje konkrétní periferii I2C. Povolené hodnoty závisí na konkrétním portu/desce. Některé porty mají výchozí hodnotu, v takovém případě lze tento parametr vynechat.

  • addr je I2C adresa targetu.

  • addrsize je počet bitů v adrese I2C targetu. Platné hodnoty jsou 7 a 10.

  • mem je objekt s buffer protokolem, do kterého lze zapisovat. Pokud není zadán, pak neexistuje žádná podpůrná paměť a data musí být čtena/zapisována pomocí metod I2CTarget.readinto() a I2CTarget.write().

  • mem_addrsize je počet bitů v adrese paměti. Platné hodnoty jsou 0, 8, 16, 24 a 32.

  • scl je pin objekt určující pin, který se má použít pro SCL.

  • sda je pin objekt určující pin, který se má použít pro SDA.

Pamatujte, že některé porty/desky budou mít výchozí hodnoty scl a sda, které lze v tomto konstruktoru změnit. Jiné budou mít pevné hodnoty scl a sda, které změnit nelze.

Obecné metody

deinit() None

Deinicializuje I2C target. Po zavolání této metody již hardware nebude odpovídat na požadavky na sběrnici I2C a nelze volat žádné další metody.

readinto(buf: bytearray) int

Načte do daného bufferu jakékoli čekající bajty zapsané I2C řadičem. Vrací počet načtených bajtů.

write(buf: bytes) int

Zapíše bajty z daného bufferu, které mají být předány I2C řadiči poté, co odešle požadavek na čtení. Vrací počet zapsaných bajtů. Většina portů přijímá touto metodou pouze jeden bajt najednou.

irq(handler: Callable[[I2CTarget], None] | None = None, trigger: int = IRQ_END_READ | IRQ_END_WRITE, hard: bool = False) None

Nainstaluje IRQ obslužnou rutinu handler, která je vyvolána, když se spustí jedna z událostí vybraných pomocí trigger. trigger je bitová maska konstant IRQ_* sloučených operací OR; výchozí nastavení se spouští na konci každého čtení nebo zápisu na straně řadiče.

hard=True registruje obsluhu tvrdého přerušení (žádná alokace na haldě v callbacku). Výchozí je naplánovaný callback. Předáním handler=None přerušení zakážete.

Poznámka

IRQ_ADDR_MATCH_READ, IRQ_ADDR_MATCH_WRITE, IRQ_READ_REQ a IRQ_WRITE_REQ musí být zpracovány callbackem tvrdého IRQ (hard=True), protože události musí být potvrzeny synchronně s hardwarem. IRQ_END_READ a IRQ_END_WRITE mohou být zpracovány buď měkkým, nebo tvrdým callbackem; všechny události sdílejí jednu obslužnou rutinu, takže pokud kterákoli událost vyžaduje tvrdý callback, vyžadují jej všechny.

Když je konstruktoru dodán paměťový buffer, ovladač potlačí IRQ_END_WRITE pro transakci, která pouze zapisuje adresu paměti. Tím zůstávají události konce transakce smysluplné i v případě, že plánovač měkkých IRQ odloží callback.

memaddr

Celočíselná hodnota nejnovější adresy paměti, kterou vybral I2C řadič (platná pouze pokud byl v konstruktoru zadán mem).

Konstanty

Každá konstanta IRQ_* je příznakový bit. Sloučením operací OR z nich sestavíte masku trigger pro irq(). Uvnitř obslužné rutiny lze sadu spuštěných událostí získat pomocí self.irq().flags() sloučené operací AND s každou konstantou.

IRQ_ADDR_MATCH_READ: int

Spustí se, když řadič adresuje tento target pro čtecí transakci (adresní bajt byl přijat s bitem čtení/zápisu nastaveným na 1). Pouze tvrdé IRQ.

IRQ_ADDR_MATCH_WRITE: int

Spustí se, když řadič adresuje tento target pro zápisovou transakci (adresní bajt byl přijat s bitem čtení/zápisu nastaveným na 0). Pouze tvrdé IRQ.

IRQ_READ_REQ: int

Spustí se, když řadič požaduje bajt od targetu. Obslužná rutina musí zavolat write() k dodání bajtu, než se dokončí hodinový cyklus řadiče. Pouze tvrdé IRQ.

IRQ_WRITE_REQ: int

Spustí se, když řadič nahodinoval bajt do targetu. Obslužná rutina musí zavolat readinto() k získání bajtu, než řadič odešle další. Pouze tvrdé IRQ.

IRQ_END_READ: int

Spustí se, když řadič dokončil čtecí transakci (přijal STOP / opakovaný START). Může být zpracováno buď tvrdým, nebo měkkým IRQ callbackem.

IRQ_END_WRITE: int

Spustí se, když řadič dokončil zápisovou transakci (přijal STOP / opakovaný START). Může být zpracováno buď tvrdým, nebo měkkým IRQ callbackem. Potlačeno pro transakci, která zapisuje adresu paměti, když byl konstruktoru dodán buffer mem.