class I2CTarget – een I2C-targetapparaat

Een I2C-target is een apparaat dat verbinding maakt met een I2C-bus en wordt aangestuurd door een I2C-controller. I2C-targets kunnen vele vormen aannemen. De machine.I2CTarget-klasse implementeert een I2C-target die kan worden geconfigureerd als een geheugen-/registerapparaat, of als een willekeurig I2C-apparaat met behulp van callbacks (indien ondersteund door de port).

Beschikbaar op de OpenMV Cam M4 / M7 / H7 / H7 Plus / Pure Thermal / RT1062 / AE3.

Voorbeeldgebruik voor het geval van een geheugenapparaat:

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

Merk op dat sommige ports een id, en mogelijk scl- en sda-pinnen, vereisen die aan de I2CTarget-constructor moeten worden doorgegeven om de hardware-I2C-instantie en de pinnen waarmee deze verbinding maakt te selecteren.

Wanneer het is geconfigureerd als een geheugenapparaat, is het ook mogelijk om u te registreren om gebeurtenissen te ontvangen. Bijvoorbeeld om op de hoogte te worden gebracht wanneer het geheugen wordt gelezen/geschreven:

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)

Complexere I2C-apparaten kunnen worden geïmplementeerd met de volledige set gebeurtenissen. Bijvoorbeeld om de ruwe gebeurtenissen te zien terwijl ze worden geactiveerd:

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)

Constructors

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)

Construeer en retourneer een nieuw I2CTarget-object met de volgende parameters:

  • id identificeert een bepaald I2C-randapparaat. Toegestane waarden hangen af van de specifieke port/board. Sommige ports hebben een standaardwaarde, in welk geval deze parameter kan worden weggelaten.

  • addr is het I2C-adres van de target.

  • addrsize is het aantal bits in het I2C-targetadres. Geldige waarden zijn 7 en 10.

  • mem is een object met het bufferprotocol dat beschrijfbaar is. Als dit niet is opgegeven, is er geen onderliggend geheugen en moet data worden gelezen/geschreven met de methoden I2CTarget.readinto() en I2CTarget.write().

  • mem_addrsize is het aantal bits in het geheugenadres. Geldige waarden zijn 0, 8, 16, 24 en 32.

  • scl is een pin-object dat de te gebruiken pin voor SCL aangeeft.

  • sda is een pin-object dat de te gebruiken pin voor SDA aangeeft.

Merk op dat sommige ports/boards standaardwaarden voor scl en sda hebben die in deze constructor kunnen worden gewijzigd. Andere hebben vaste waarden voor scl en sda die niet kunnen worden gewijzigd.

Algemene methoden

deinit() None

De-initialiseer de I2C-target. Nadat deze methode is aangeroepen, reageert de hardware niet langer op verzoeken op de I2C-bus en kunnen er geen andere methoden worden aangeroepen.

readinto(buf: bytearray) int

Lees in de gegeven buffer eventuele in behandeling zijnde bytes die door de I2C-controller zijn geschreven. Retourneert het aantal gelezen bytes.

write(buf: bytes) int

Schrijf de bytes uit de gegeven buffer uit, om aan de I2C-controller te worden doorgegeven nadat deze een leesverzoek verzendt. Retourneert het aantal geschreven bytes. De meeste ports accepteren slechts één byte tegelijk voor deze methode.

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

Installeer een IRQ-handler die wordt aangeroepen wanneer een van de door trigger geselecteerde gebeurtenissen optreedt. trigger is een bitmasker van IRQ_*-constanten die met OR zijn gecombineerd; de standaardwaarde treedt op bij het einde van elke controllerzijdige lees- of schrijfactie.

hard=True registreert een hard-interrupt-handler (geen heap-allocatie in de callback). De standaardwaarde is een geplande callback. Geef handler=None door om de interrupt uit te schakelen.

Notitie

IRQ_ADDR_MATCH_READ, IRQ_ADDR_MATCH_WRITE, IRQ_READ_REQ en IRQ_WRITE_REQ moeten worden afgehandeld door een hard-IRQ-callback (hard=True) omdat de gebeurtenissen synchroon met de hardware moeten worden bevestigd. IRQ_END_READ en IRQ_END_WRITE kunnen worden afgehandeld door zowel soft- als hard-callbacks; alle gebeurtenissen delen één enkele handler, dus als een gebeurtenis een hard-callback nodig heeft, dan hebben ze die allemaal nodig.

Wanneer een geheugenbuffer aan de constructor wordt geleverd, onderdrukt de driver IRQ_END_WRITE voor de transactie die slechts het geheugenadres schrijft. Dit houdt de einde-van-transactie-gebeurtenissen betekenisvol, zelfs wanneer de soft-IRQ-scheduler de callback uitstelt.

memaddr

De gehele waarde van het meest recente geheugenadres dat door de I2C-controller is geselecteerd (alleen geldig als mem is opgegeven in de constructor).

Constanten

Elke IRQ_*-constante is een vlagbit. Combineer ze met OR om een trigger-masker voor irq() te bouwen. Binnen de handler kan de set van opgetreden gebeurtenissen worden achterhaald via self.irq().flags() gecombineerd met AND met elke constante.

IRQ_ADDR_MATCH_READ: int

Treedt op wanneer een controller deze target adresseert voor een leestransactie (de adresbyte is ontvangen met de lees-/schrijfbit ingesteld op 1). Alleen hard-IRQ.

IRQ_ADDR_MATCH_WRITE: int

Treedt op wanneer een controller deze target adresseert voor een schrijftransactie (de adresbyte is ontvangen met de lees-/schrijfbit ingesteld op 0). Alleen hard-IRQ.

IRQ_READ_REQ: int

Treedt op wanneer de controller een byte van de target opvraagt. De handler moet write() aanroepen om de byte te leveren voordat de klokcyclus van de controller is voltooid. Alleen hard-IRQ.

IRQ_WRITE_REQ: int

Treedt op wanneer de controller een byte naar de target heeft ingeklokt. De handler moet readinto() aanroepen om de byte op te halen voordat de controller de volgende verzendt. Alleen hard-IRQ.

IRQ_END_READ: int

Treedt op wanneer de controller een leestransactie heeft voltooid (STOP / herhaalde START ontvangen). Kan worden afgehandeld door zowel een hard- als een soft-IRQ-callback.

IRQ_END_WRITE: int

Treedt op wanneer de controller een schrijftransactie heeft voltooid (STOP / herhaalde START ontvangen). Kan worden afgehandeld door zowel een hard- als een soft-IRQ-callback. Onderdrukt voor de transactie die het geheugenadres schrijft wanneer een mem-buffer aan de constructor is geleverd.