clasa I2CTarget – un dispozitiv țintă I2C¶
O țintă I2C este un dispozitiv care se conectează la o magistrală I2C și este controlat de un controller I2C. Țintele I2C pot lua multe forme. Clasa machine.I2CTarget implementează o țintă I2C care poate fi configurată ca dispozitiv de memorie/registre sau ca un dispozitiv I2C arbitrar folosind funcții de retroapelare (callback) (dacă este suportat de port).
Disponibil pe OpenMV Cam M4 / M7 / H7 / H7 Plus / Pure Thermal / RT1062 / AE3.
Exemplu de utilizare pentru cazul unui dispozitiv de memorie:
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()
Rețineți că unele porturi necesită ca un id și, eventual, pinii scl și sda să fie transmiși constructorului I2CTarget, pentru a selecta instanța hardware I2C și pinii la care se conectează.
Când este configurat ca dispozitiv de memorie, este de asemenea posibil să vă înregistrați pentru a primi evenimente. De exemplu, pentru a fi notificat când memoria este citită/scrisă:
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)
Dispozitivele I2C mai complicate pot fi implementate folosind setul complet de evenimente. De exemplu, pentru a vedea evenimentele brute pe măsură ce sunt declanșate:
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)
Constructori¶
- 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)¶
Construiește și returnează un nou obiect I2CTarget folosind următorii parametri:
id identifică un anumit periferic I2C. Valorile permise depind de portul/placa anume. Unele porturi au o valoare implicită, caz în care acest parametru poate fi omis.
addr este adresa I2C a țintei.
addrsize este numărul de biți din adresa țintei I2C. Valorile valide sunt 7 și 10.
mem este un obiect cu protocolul buffer care este inscriptibil. Dacă nu este specificat, atunci nu există memorie de fundal, iar datele trebuie citite/scrise folosind metodele
I2CTarget.readinto()șiI2CTarget.write().mem_addrsize este numărul de biți din adresa de memorie. Valorile valide sunt 0, 8, 16, 24 și 32.
scl este un obiect pin care specifică pinul de utilizat pentru SCL.
sda este un obiect pin care specifică pinul de utilizat pentru SDA.
Rețineți că unele porturi/plăci vor avea valori implicite pentru scl și sda care pot fi modificate în acest constructor. Altele vor avea valori fixe pentru scl și sda care nu pot fi modificate.
Metode generale¶
- deinit() None¶
Dezinițializează ținta I2C. După apelarea acestei metode, hardware-ul nu va mai răspunde la cererile de pe magistrala I2C și nu mai pot fi apelate alte metode.
- readinto(buf: bytearray) int¶
Citește în tamponul dat orice octeți în așteptare scriși de controllerul I2C. Returnează numărul de octeți citiți.
- write(buf: bytes) int¶
Scrie octeții din tamponul dat, pentru a fi transmiși controllerului I2C după ce acesta trimite o cerere de citire. Returnează numărul de octeți scriși. Majoritatea porturilor acceptă doar un octet la un moment dat pentru această metodă.
- irq(handler: Callable[[I2CTarget], None] | None = None, trigger: int = IRQ_END_READ | IRQ_END_WRITE, hard: bool = False) None¶
Instalează un gestionar de IRQ
handlercare este invocat când se declanșează unul dintre evenimentele selectate detrigger.triggereste o mască de biți de constanteIRQ_*combinate cu OR; valoarea implicită se declanșează la sfârșitul fiecărei citiri sau scrieri din partea controllerului.hard=Trueînregistrează un gestionar de întrerupere hard (fără alocare de heap în funcția de retroapelare). Valoarea implicită este o funcție de retroapelare programată. Transmitețihandler=Nonepentru a dezactiva întreruperea.Notă
IRQ_ADDR_MATCH_READ,IRQ_ADDR_MATCH_WRITE,IRQ_READ_REQșiIRQ_WRITE_REQtrebuie gestionate de o funcție de retroapelare IRQ hard (hard=True) deoarece evenimentele trebuie confirmate sincron cu hardware-ul.IRQ_END_READșiIRQ_END_WRITEpot fi gestionate fie de funcții de retroapelare soft, fie hard; toate evenimentele împart un singur gestionar, deci dacă vreun eveniment necesită o funcție de retroapelare hard, atunci toate o necesită.Atunci când un tampon de memorie este furnizat constructorului, driverul suprimă
IRQ_END_WRITEpentru tranzacția care doar scrie adresa de memorie. Acest lucru menține semnificative evenimentele de sfârșit de tranzacție chiar și atunci când planificatorul de IRQ-uri soft amână funcția de retroapelare.
- memaddr¶
Valoarea întreagă a celei mai recente adrese de memorie care a fost selectată de controllerul I2C (validă doar dacă
mema fost specificat în constructor).
Constante¶
Fiecare constantă
IRQ_*este un bit de indicator. Combinați-le cu OR pentru a construi o mascătriggerpentruirq(). În interiorul gestionarului, setul de evenimente declanșate poate fi recuperat prinself.irq().flags()combinat cu AND cu fiecare constantă.- IRQ_ADDR_MATCH_READ: int¶
Se declanșează când un controller adresează această țintă pentru o tranzacție de citire (octetul de adresă a fost primit cu bitul de citire/scriere setat la
1). Doar IRQ hard.
- IRQ_ADDR_MATCH_WRITE: int¶
Se declanșează când un controller adresează această țintă pentru o tranzacție de scriere (octetul de adresă a fost primit cu bitul de citire/scriere setat la
0). Doar IRQ hard.
- IRQ_READ_REQ: int¶
Se declanșează când controllerul solicită un octet de la țintă. Gestionarul trebuie să apeleze
write()pentru a furniza octetul înainte ca ciclul de ceas al controllerului să se încheie. Doar IRQ hard.
- IRQ_WRITE_REQ: int¶
Se declanșează când controllerul a transmis un octet către țintă. Gestionarul trebuie să apeleze
readinto()pentru a prelua octetul înainte ca controllerul să-l trimită pe următorul. Doar IRQ hard.
- IRQ_END_READ: int¶
Se declanșează când controllerul a terminat o tranzacție de citire (a primit STOP / START repetat). Poate fi gestionat fie de o funcție de retroapelare IRQ hard, fie soft.
- IRQ_END_WRITE: int¶
Se declanșează când controllerul a terminat o tranzacție de scriere (a primit STOP / START repetat). Poate fi gestionat fie de o funcție de retroapelare IRQ hard, fie soft. Suprimat pentru tranzacția care scrie adresa de memorie atunci când un tampon
mema fost furnizat constructorului.