class I2CTarget – un périphérique cible I2C¶
Une cible I2C est un périphérique qui se connecte à un bus I2C et qui est contrôlé par un contrôleur I2C. Les cibles I2C peuvent prendre de nombreuses formes. La classe machine.I2CTarget implémente une cible I2C qui peut être configurée comme un dispositif de mémoire/registre, ou comme un périphérique I2C arbitraire à l’aide de fonctions de rappel (si le port le prend en charge).
Disponible sur l’OpenMV Cam M4 / M7 / H7 / H7 Plus / Pure Thermal / RT1062 / AE3.
Exemple d’utilisation dans le cas d’un dispositif de mémoire
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()
Notez que certains ports nécessitent qu’un id, et éventuellement des broches scl et sda, soient passés au constructeur I2CTarget afin de sélectionner l’instance I2C matérielle et les broches auxquelles elle se connecte.
Lorsqu’il est configuré comme un dispositif de mémoire, il est également possible de s’enregistrer pour recevoir des événements. Par exemple, pour être notifié lorsque la mémoire est lue/écrite
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)
Des périphériques I2C plus complexes peuvent être implémentés à l’aide de l’ensemble complet des événements. Par exemple, pour visualiser les événements bruts au fur et à mesure de leur déclenchement
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)
Constructeurs¶
- 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)¶
Construit et renvoie un nouvel objet I2CTarget en utilisant les paramètres suivants :
id identifie un périphérique I2C particulier. Les valeurs autorisées dépendent du port/de la carte considérés. Certains ports ont une valeur par défaut, auquel cas ce paramètre peut être omis.
addr est l’adresse I2C de la cible.
addrsize est le nombre de bits de l’adresse de la cible I2C. Les valeurs valides sont 7 et 10.
mem est un objet prenant en charge le protocole tampon et accessible en écriture. S’il n’est pas spécifié, il n’y a pas de mémoire sous-jacente et les données doivent être lues/écrites à l’aide des méthodes
I2CTarget.readinto()etI2CTarget.write().mem_addrsize est le nombre de bits de l’adresse mémoire. Les valeurs valides sont 0, 8, 16, 24 et 32.
scl est un objet broche spécifiant la broche à utiliser pour SCL.
sda est un objet broche spécifiant la broche à utiliser pour SDA.
Notez que certains ports/cartes auront des valeurs par défaut de scl et sda qui peuvent être modifiées dans ce constructeur. D’autres auront des valeurs fixes de scl et sda qui ne peuvent pas être modifiées.
Méthodes générales¶
- deinit() None¶
Désinitialise la cible I2C. Après l’appel de cette méthode, le matériel ne répondra plus aux requêtes sur le bus I2C, et aucune autre méthode ne pourra être appelée.
- readinto(buf: bytearray) int¶
Lit dans le tampon donné les octets en attente écrits par le contrôleur I2C. Renvoie le nombre d’octets lus.
- write(buf: bytes) int¶
Écrit les octets du tampon donné, destinés à être transmis au contrôleur I2C après qu’il a envoyé une requête de lecture. Renvoie le nombre d’octets écrits. La plupart des ports n’acceptent qu’un seul octet à la fois pour cette méthode.
- irq(handler: Callable[[I2CTarget], None] | None = None, trigger: int = IRQ_END_READ | IRQ_END_WRITE, hard: bool = False) None¶
Installe un gestionnaire d’IRQ
handlerqui est invoqué lorsque l’un des événements sélectionnés partriggerse déclenche.triggerest un masque binaire de constantesIRQ_*combinées par OU ; par défaut, le déclenchement se produit à la fin de chaque lecture ou écriture côté contrôleur.hard=Trueenregistre un gestionnaire d’interruption matérielle (pas d’allocation sur le tas dans la fonction de rappel). La valeur par défaut est une fonction de rappel planifiée. Passezhandler=Nonepour désactiver l’interruption.Note
IRQ_ADDR_MATCH_READ,IRQ_ADDR_MATCH_WRITE,IRQ_READ_REQetIRQ_WRITE_REQdoivent être traités par une fonction de rappel d’IRQ matérielle (hard=True) car ces événements doivent être acquittés de façon synchrone avec le matériel.IRQ_END_READetIRQ_END_WRITEpeuvent être traités par des fonctions de rappel logicielles ou matérielles ; tous les événements partagent un unique gestionnaire, donc si un événement nécessite une fonction de rappel matérielle, tous la nécessitent.Lorsqu’un tampon mémoire est fourni au constructeur, le pilote supprime l’événement
IRQ_END_WRITEpour la transaction qui ne fait qu’écrire l’adresse mémoire. Cela préserve le sens des événements de fin de transaction, même lorsque le planificateur d’IRQ logicielles diffère la fonction de rappel.
- memaddr¶
La valeur entière de la dernière adresse mémoire qui a été sélectionnée par le contrôleur I2C (valide uniquement si
mema été spécifié dans le constructeur).
Constantes¶
Chaque constante
IRQ_*est un bit indicateur. Combinez-les par OU pour construire un masquetriggerpourirq(). À l’intérieur du gestionnaire, l’ensemble des événements déclenchés peut être récupéré viaself.irq().flags()combiné par ET avec chaque constante.- IRQ_ADDR_MATCH_READ: int¶
Se déclenche lorsqu’un contrôleur adresse cette cible pour une transaction de lecture (l’octet d’adresse a été reçu avec le bit de lecture/écriture positionné à
1). IRQ matérielle uniquement.
- IRQ_ADDR_MATCH_WRITE: int¶
Se déclenche lorsqu’un contrôleur adresse cette cible pour une transaction d’écriture (l’octet d’adresse a été reçu avec le bit de lecture/écriture positionné à
0). IRQ matérielle uniquement.
- IRQ_READ_REQ: int¶
Se déclenche lorsque le contrôleur demande un octet à la cible. Le gestionnaire doit appeler
write()pour fournir l’octet avant la fin du cycle d’horloge du contrôleur. IRQ matérielle uniquement.
- IRQ_WRITE_REQ: int¶
Se déclenche lorsque le contrôleur a transféré un octet vers la cible. Le gestionnaire doit appeler
readinto()pour récupérer l’octet avant que le contrôleur n’envoie le suivant. IRQ matérielle uniquement.
- IRQ_END_READ: int¶
Se déclenche lorsque le contrôleur a terminé une transaction de lecture (réception d’un STOP / d’un START répété). Peut être traité par une fonction de rappel d’IRQ matérielle ou logicielle.
- IRQ_END_WRITE: int¶
Se déclenche lorsque le contrôleur a terminé une transaction d’écriture (réception d’un STOP / d’un START répété). Peut être traité par une fonction de rappel d’IRQ matérielle ou logicielle. Supprimé pour la transaction qui écrit l’adresse mémoire lorsqu’un tampon
mema été fourni au constructeur.