třída I2C – dvouvodičový sériový protokol

I2C je dvouvodičový protokol pro komunikaci mezi zařízeními. Na fyzické úrovni se skládá ze 2 vodičů: SCL a SDA, což jsou hodinová a datová linka.

Objekty I2C se vytvářejí připojené ke konkrétní sběrnici. Mohou být inicializovány při vytvoření, nebo inicializovány později.

Vypsání objektu I2C vám poskytne informace o jeho konfiguraci.

K dispozici jsou hardwarové i softwarové implementace I2C prostřednictvím tříd I2C a SoftI2C. Hardwarové I2C využívá pro provádění čtení/zápisů podpůrný hardware systému a je obvykle efektivní a rychlé, ale může mít omezení ohledně toho, které piny lze použít. Softwarové I2C je implementováno bit-bangingem a lze jej použít na libovolném pinu, ale není tak efektivní. Tyto třídy mají k dispozici stejné metody a liší se především způsobem, jakým se konstruují.

Poznámka

Sběrnice I2C vyžaduje pro svůj provoz pull-up obvody na SDA i SCL. Obvykle se jedná o rezistory v rozsahu 1 - 10 kOhm, zapojené z každé linky SDA/SCL na Vcc. Bez nich je chování nedefinované a může se pohybovat od blokování, neočekávaného resetu watchdogu až po prostě nesprávné hodnoty. Tyto pull-up obvody jsou často již zabudovány do desky MCU nebo do breakout desek senzorů, ale neexistuje na to žádné pravidlo. Proto si to v případě problémů prosím zkontrolujte. Viz také tento vynikající průvodce od Adafruit o zapojení I2C.

Příklad použití:

from machine import I2C

i2c = I2C(freq=400000)          # create I2C peripheral at frequency of 400kHz
                                # depending on the port, extra parameters may be required
                                # to select the peripheral and/or pins to use

i2c.scan()                      # scan for peripherals, returning a list of 7-bit addresses

i2c.writeto(42, b'123')         # write 3 bytes to peripheral with 7-bit address 42
i2c.readfrom(42, 4)             # read 4 bytes from peripheral with 7-bit address 42

i2c.readfrom_mem(42, 8, 3)      # read 3 bytes from memory of peripheral 42,
                                #   starting at memory-address 8 in the peripheral
i2c.writeto_mem(42, 2, b'\x10') # write 1 byte to memory of peripheral 42
                                #   starting at address 2 in the peripheral

Konstruktory

class machine.I2C(id: int, *, scl: Pin | None = None, sda: Pin | None = None, freq: int = 400000, timeout: int = 50000)

Vytvoří a vrátí nový objekt I2C 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

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

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

  • freq by mělo být celé číslo, které nastavuje maximální frekvenci pro SCL.

  • timeout je maximální čas v mikrosekundách povolený pro I2C transakce. Tento parametr není na některých portech povolen.

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

init(scl: Pin, sda: Pin, *, freq: int = 400000) None

Inicializuje sběrnici I2C s danými argumenty:

  • scl je pin objekt pro linku SCL

  • sda je pin objekt pro linku SDA

  • freq je hodinová frekvence SCL

V případě hardwarového I2C může být skutečná hodinová frekvence nižší než požadovaná frekvence. To závisí na hardwaru platformy. Skutečnou frekvenci lze zjistit vypsáním objektu I2C.

scan() List[int]

Prohledá všechny I2C adresy od 0x08 do 0x77 včetně a vrátí seznam těch, které odpovědí. Zařízení odpoví, pokud po odeslání své adresy (včetně zápisového bitu) na sběrnici stáhne linku SDA do nízké úrovně.

Primitivní I2C operace

Následující metody implementují primitivní operace řadiče sběrnice I2C a lze je kombinovat k vytvoření libovolné I2C transakce. Jsou poskytovány pro případ, že potřebujete větší kontrolu nad sběrnicí, jinak lze použít standardní metody (viz níže).

Tyto metody jsou dostupné pouze ve třídě SoftI2C.

start() None

Vygeneruje na sběrnici podmínku START (SDA přechází do nízké úrovně, zatímco SCL je ve vysoké úrovni).

stop() None

Vygeneruje na sběrnici podmínku STOP (SDA přechází do vysoké úrovně, zatímco SCL je ve vysoké úrovni).

readinto(buf: bytearray, nack: bool = True, /) None

Načte bajty ze sběrnice a uloží je do buf. Počet načtených bajtů odpovídá délce buf. Po přijetí všech bajtů kromě posledního bude na sběrnici odeslán ACK. Po přijetí posledního bajtu, pokud je nack true, bude odeslán NACK, jinak bude odeslán ACK (a v tomto případě periferie předpokládá, že v pozdějším volání bude načteno více bajtů).

write(buf: bytes) int

Zapíše bajty z buf na sběrnici. Kontroluje, zda je po každém bajtu přijat ACK, a pokud je přijat NACK, přestane vysílat zbývající bajty. Funkce vrací počet přijatých ACK.

Standardní operace sběrnice

Následující metody implementují standardní operace čtení a zápisu řadiče I2C, které cílí na dané periferní zařízení.

readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes

Načte nbytes z periferie určené addr. Pokud je stop true, pak je na konci přenosu vygenerována podmínka STOP. Vrací objekt bytes s načtenými daty.

readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None

Načte data do buf z periferie určené addr. Počet načtených bajtů bude odpovídat délce buf. Pokud je stop true, pak je na konci přenosu vygenerována podmínka STOP.

Tato metoda vrací None.

writeto(addr: int, buf: bytes, stop: bool = True, /) int

Zapíše bajty z buf do periferie určené addr. Pokud je po zápisu bajtu z buf přijat NACK, pak zbývající bajty nejsou odeslány. Pokud je stop true, pak je na konci přenosu vygenerována podmínka STOP, a to i v případě přijetí NACK. Funkce vrací počet přijatých ACK.

writevto(addr: int, vector: tuple | list, stop: bool = True, /) int

Zapíše bajty obsažené ve vector do periferie určené addr. vector by měl být tuple nebo seznam objektů s buffer protokolem. addr se odešle jednou a poté se sekvenčně zapíší bajty z každého objektu ve vector. Objekty ve vector mohou mít nulovou délku v bajtech, v takovém případě nepřispívají k výstupu.

Pokud je po zápisu bajtu z jednoho z objektů ve vector přijat NACK, pak zbývající bajty a jakékoli zbývající objekty nejsou odeslány. Pokud je stop true, pak je na konci přenosu vygenerována podmínka STOP, a to i v případě přijetí NACK. Funkce vrací počet přijatých ACK.

Operace s pamětí

Některá I2C zařízení se chovají jako paměťové zařízení (nebo sada registrů), ze kterého lze číst a do kterého lze zapisovat. V tomto případě jsou s I2C transakcí spojeny dvě adresy: adresa periferie a adresa paměti. Následující metody jsou pohodlné funkce pro komunikaci s takovými zařízeními.

readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes

Načte nbytes z periferie určené addr počínaje adresou paměti určenou memaddr. Argument addrsize určuje velikost adresy v bitech. Vrací objekt bytes s načtenými daty.

readfrom_mem_into(addr: int, memaddr: int, buf: bytearray, *, addrsize: int = 8) None

Načte data do buf z periferie určené addr počínaje adresou paměti určenou memaddr. Počet načtených bajtů odpovídá délce buf. Argument addrsize určuje velikost adresy v bitech.

Tato metoda vrací None.

writeto_mem(addr: int, memaddr: int, buf: bytes, *, addrsize: int = 8) None

Zapíše buf do periferie určené addr počínaje adresou paměti určenou memaddr. Argument addrsize určuje velikost adresy v bitech.

Tato metoda vrací None.

třída SoftI2C – softwarově emulovaná sběrnice I2C

Třída SoftI2C implementuje I2C bit-bangingem libovolných GPIO pinů. Poskytuje stejnou sadu metod jako I2C plus nízkoúrovňové primitivní operace sběrnice (start(), stop(), readinto(), write()) pro volající, kteří potřebují sestavit nestandardní transakce. Použijte ji, když piny, které potřebujete, nejsou připojeny k hardwarovému I2C bloku, když potřebujete více sběrnic, než hardware poskytuje, nebo pro komunikaci se zařízeními, která vyžadují neobvyklé sekvence (extra hodinové impulsy, opakované starty po zápisech atd.).

Konstruktory

class machine.SoftI2C(scl: Pin, sda: Pin, *, freq: int = 400000, timeout: int = 50000)

Vytvoří softwarovou sběrnici I2C řízenou scl / sda.

freq je cílová hodinová frekvence SCL v Hz (skutečná frekvence je obvykle nižší kvůli režii smyčky bit-bangingu).

timeout je maximální čas v mikrosekundách pro čekání na clock stretching (SCL drženou v nízké úrovni jiným zařízením na sběrnici); po jeho vypršení je vyvolána výjimka OSError(ETIMEDOUT).

Obecné metody

init(scl: Pin, sda: Pin, *, freq: int = 400000) None

Znovu inicializuje softwarovou sběrnici I2C s danými piny a frekvencí. Ekvivalentní zkonstruování nového SoftI2C na stejném objektu.

scan() List[int]

Prohledá všechny I2C adresy od 0x08 do 0x77 včetně a vrátí seznam těch, které odpověděly.

Primitivní I2C operace

Následující metody implementují primitivní operace řadiče sběrnice I2C a lze je kombinovat k vytvoření libovolné I2C transakce. Jsou pouze pro SoftI2C – hardwarová třída I2C je neposkytuje.

start() None

Vygeneruje na sběrnici podmínku START (SDA přechází do nízké úrovně, zatímco SCL je ve vysoké úrovni).

stop() None

Vygeneruje na sběrnici podmínku STOP (SDA přechází do vysoké úrovně, zatímco SCL je ve vysoké úrovni).

readinto(buf: bytearray, nack: bool = True, /) None

Načte bajty ze sběrnice do buf. Načte se len(buf) bajtů; po každém bajtu kromě posledního se odešle ACK. Po posledním bajtu nack=True (výchozí) odešle NACK pro ukončení přenosu; nack=False odešle ACK, takže zařízení zůstane vybráno pro následné readinto().

write(buf: bytes) int

Zapíše buf na sběrnici a po každém bajtu kontroluje ACK. Vysílání se zastaví při prvním NACK. Vrací počet přijatých ACK.

Standardní operace sběrnice

Následující metody implementují standardní operace čtení a zápisu řadiče I2C, které cílí na dané periferní zařízení.

readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes

Načte nbytes ze zařízení na 7bitové adrese addr. Pokud je stop true, na konci přenosu se vygeneruje podmínka STOP.

readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None

Načte len(buf) bajtů ze zařízení na adrese addr do buf. Pokud je stop true, na konci přenosu se vygeneruje podmínka STOP.

writeto(addr: int, buf: bytes, stop: bool = True, /) int

Zapíše buf do zařízení na adrese addr. Vysílání se zastaví při prvním NACK. Pokud je stop true, na konci přenosu se vždy vygeneruje podmínka STOP (i při předčasném NACK). Vrací počet přijatých ACK.

writevto(addr: int, vector: tuple | list, stop: bool = True, /) int

Zapíše zřetězení bufferů z vector do zařízení na adrese addr jako jednu transakci. Prázdné buffery jsou ignorovány. Pro sémantiku stop a návratovou hodnotu se chová jako writeto().

Operace s pamětí

Některá I2C zařízení se chovají jako paměťové zařízení (nebo sada registrů), ze kterého lze číst a do kterého lze zapisovat. V tomto případě jsou s I2C transakcí spojeny dvě adresy: adresa periferie a adresa paměti. Následující metody jsou pohodlní pomocníci pro komunikaci s takovými zařízeními.

readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes

Načte nbytes ze zařízení na adrese addr počínaje registrem memaddr. addrsize je šířka adresy registru v bitech (obvykle 8 nebo 16).

readfrom_mem_into(addr: int, memaddr: int, buf: bytearray, *, addrsize: int = 8) None

Načte data do buf ze zařízení na adrese addr počínaje registrem memaddr.

writeto_mem(addr: int, memaddr: int, buf: bytes, *, addrsize: int = 8) None

Zapíše buf do zařízení na adrese addr počínaje registrem memaddr.