klasa CAN – komunikacijska sabirnica controller area network

CAN podržava i klasični CAN (bxCAN, koji se koristi na OpenMV Cam M4 i M7) i CAN FD (FDCAN, koji se koristi na OpenMV Cam H7, H7 Plus i Pure Thermal) kontrolere. Na fizičkoj razini CAN sabirnica sastoji se od dvije linije, RX i TX. Za spajanje OpenMV Cam na CAN sabirnicu morate koristiti CAN primopredajnik koji pretvara logičke CAN signale iz MCU-a u ispravne naponske razine na sabirnici.

Klasični CAN u petljanom (loopback) načinu rada bez primopredajnika:

from pyb import CAN

can = CAN(1, CAN.LOOPBACK)

# Accept messages with id 123, 124, 125 or 126.
can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126))

can.send("message!", 123)   # send a message with id 123
can.recv(0)                 # receive a message on FIFO 0

CAN FD sa svim uključenim opcionalnim značajkama (FD okvir, prebacivanje brzine prijenosa, prošireni ID-ovi okvira; arbitražna faza od 500 kbit/s, podatkovna faza od 1 Mbit/s):

from pyb import CAN

can = CAN(
    1,
    CAN.NORMAL,
    baudrate=500_000,
    brs_baudrate=1_000_000,
    sample_point=80,
)

# Accept any id in the range 0xFFF0 .. 0xFFFF.
can.setfilter(0, CAN.RANGE, 0, (0xFFF0, 0xFFFF))

can.send(b"a" * 64, 0xFFFF, fdf=True, brs=True, extframe=True)
can.recv(0)

Sljedeće funkcije CAN modula i njihovi argumenti dostupni su i za klasične i za FD CAN kontrolere, osim ako nije drugačije navedeno.

Konstruktori

class pyb.CAN(bus: int | str, *args, **kwargs)

Konstruira CAN objekt na zadanoj sabirnici bus (cjelobrojni indeks periferije, npr. 1 za CAN1, 2 za CAN2). Bez dodatnih parametara objekt se stvara, ali se ne inicijalizira (zadržava prethodne postavke sabirnice, ako postoje); ako su zadani dodatni argumenti, sabirnica se inicijalizira. Pogledajte CAN.init() za dostupne parametre.

CAN(2) je ožičen na iste pinove zaglavlja na svakom OpenMV Cam koji izlaže pyb.CAN (M4 / M7 / H7 / H7 Plus / Pure Thermal):

Signal

Pin zaglavlja

Napomene

RX

P3

TX

P2

CAN periferija pruža samo signale na logičkoj razini; za pogon stvarne CAN sabirnice potreban je vanjski CAN primopredajnik.

pyb.CAN nije dostupan na OpenMV Cam N6.

Metode

init(mode: int, prescaler: int = 100, *, sjw: int = 1, bs1: int = 6, bs2: int = 8, auto_restart: bool = False, baudrate: int = 0, sample_point: int = 75, num_filter_banks: int = 14, brs_sjw: int = 1, brs_bs1: int = 8, brs_bs2: int = 3, brs_baudrate: int = 0, brs_sample_point: int = 75) None

Inicijalizira CAN sabirnicu sa zadanim parametrima:

  • mode je jedan od: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK

  • prescaler je vrijednost kojom se dijeli ulazni takt CAN-a kako bi se generirali nominalni vremenski kvanti bita. Preddjelitelj može biti vrijednost između 1 i 1024 uključivo za klasični CAN, te između 1 i 512 uključivo za CAN FD.

  • sjw je širina koraka resinkronizacije u jedinicama vremenskih kvanta za nominalne bitove; može biti vrijednost između 1 i 4 uključivo za klasični CAN, te između 1 i 128 uključivo za CAN FD.

  • bs1 definira položaj točke uzorkovanja u jedinicama vremenskih kvanta za nominalne bitove; može biti vrijednost između 1 i 16 uključivo za klasični CAN, te između 2 i 256 uključivo za CAN FD.

  • bs2 definira položaj točke prijenosa u jedinicama vremenskih kvanta za nominalne bitove; može biti vrijednost između 1 i 8 uključivo za klasični CAN, te između 2 i 128 uključivo za CAN FD.

  • auto_restart određuje hoće li kontroler automatski pokušati ponovno pokrenuti komunikaciju nakon ulaska u stanje bus-off; ako je ovo onemogućeno, tada se restart() može koristiti za izlazak iz stanja bus-off

  • baudrate ako je zadana brzina prijenosa različita od 0, ova funkcija pokušat će automatski izračunati nominalno vrijeme bita CAN-a (zaobilazeći prescaler, bs1 i bs2) koje zadovoljava i baudrate (unutar .1%) i željenu sample_point (na najbliži 1%). Za precizniju kontrolu nad CAN vremenskim odnosima, izravno postavite parametre prescaler, bs1 i bs2.

  • sample_point određuje položaj uzorka bita u odnosu na cijelo nominalno vrijeme bita, izražen kao cjelobrojni postotak nominalnog vremena bita. Zadana sample_point je 75%. Ovaj se parametar zanemaruje osim ako je postavljen baudrate.

  • num_filter_banks za klasični CAN, ovo je broj banaka koje će biti dodijeljene CAN(1), a ostatak od 28 dodjeljuje se CAN(2).

Preostali parametri prisutni su samo na pločama s podrškom za CAN FD i konfiguriraju opcionalnu značajku CAN FD Bit Rate Switch (BRS):

  • brs_prescaler je vrijednost kojom se dijeli ulazni takt CAN FD-a kako bi se generirali vremenski kvanti podatkovnog bita. Preddjelitelj može biti vrijednost između 1 i 32 uključivo.

  • brs_sjw je širina koraka resinkronizacije u jedinicama vremenskih kvanta za podatkovne bitove; može biti vrijednost između 1 i 16 uključivo

  • brs_bs1 definira položaj točke uzorkovanja u jedinicama vremenskih kvanta za podatkovne bitove; može biti vrijednost između 1 i 32 uključivo

  • brs_bs2 definira položaj točke prijenosa u jedinicama vremenskih kvanta za podatkovne bitove; može biti vrijednost između 1 i 16 uključivo

  • brs_baudrate ako je zadana brzina prijenosa različita od 0, ova funkcija pokušat će automatski izračunati podatkovno vrijeme bita CAN-a (zaobilazeći brs_prescaler, brs_bs1 i brs_bs2) koje zadovoljava i brs_baudrate (unutar .1%) i željenu brs_sample_point (na najbliži 1%). Za precizniju kontrolu nad BRS vremenskim odnosima, izravno postavite parametre brs_prescaler, brs_bs1 i brs_bs2.

  • brs_sample_point određuje položaj uzorka bita u odnosu na cijelo nominalno vrijeme bita, izražen kao cjelobrojni postotak nominalnog vremena bita. Zadana brs_sample_point je 75%. Ovaj se parametar zanemaruje osim ako je postavljen brs_baudrate.

Vremenski kvant tq je osnovna jedinica vremena za CAN sabirnicu. tq je vrijednost CAN predjelitelja podijeljena s PCLK1 (frekvencija interne periferne sabirnice 1); pogledajte pyb.freq() za određivanje PCLK1.

Pojedini bit sastoji se od segmenta sinkronizacije, koji je uvijek 1 tq. Zatim slijedi segment bita 1, pa segment bita 2. Točka uzorkovanja je nakon završetka segmenta bita 1. Točka prijenosa je nakon završetka segmenta bita 2. Brzina prijenosa bit će 1/bittime, gdje je bittime jednak 1 + BS1 + BS2 pomnoženo s vremenskim kvantom tq.

Na primjer, na OpenMV Cam H7 (PCLK1 = 100 MHz), CAN od 250 kbps s točkom uzorkovanja na 75% može se konfigurirati kao prescaler=25, sjw=1, bs1=11, bs2=4: tq = 25 / 100 MHz = 250 ns, bittime = (1 + 11 + 4) × 250 ns = 4 µs, točka uzorkovanja = (1 + 11) / 16 = 75%, a brzina prijenosa je 1 / 4 µs = 250 kHz.

Pogledajte odjeljak bxCAN / FDCAN u referentnom priručniku STM32 za MCU vašeg OpenMV Cam za više pojedinosti.

deinit() None

Isključuje CAN sabirnicu.

restart() None

Prisilno softverski ponovno pokreće CAN kontroler bez poništavanja njegove konfiguracije.

Ako kontroler uđe u stanje bus-off, tada više neće sudjelovati u aktivnosti sabirnice. Ako kontroler nije konfiguriran za automatsko ponovno pokretanje (pogledajte init()), tada se ova metoda može koristiti za pokretanje ponovnog pokretanja, a kontroler će slijediti CAN protokol kako bi napustio stanje bus-off i prešao u stanje error active.

state() int

Vraća stanje kontrolera. Povratna vrijednost može biti jedna od:

  • CAN.STOPPED – kontroler je potpuno isključen i resetiran;

  • CAN.ERROR_ACTIVE – kontroler je uključen i u stanju Error Active (i TEC i REC su manji od 96);

  • CAN.ERROR_WARNING – kontroler je uključen i u stanju Error Warning (barem jedan od TEC ili REC je 96 ili veći);

  • CAN.ERROR_PASSIVE – kontroler je uključen i u stanju Error Passive (barem jedan od TEC ili REC je 128 ili veći);

  • CAN.BUS_OFF – kontroler je uključen, ali ne sudjeluje u aktivnosti sabirnice (TEC je prešao 255).

info(list: list | None = None) list

Dohvaća informacije o stanjima pogreške kontrolera te o TX i RX međuspremnicima. Ako je zadan list, tada bi to trebao biti objekt liste s najmanje 8 unosa, koji će biti popunjeni informacijama. U suprotnom, stvorit će se nova lista i popuniti. U oba slučaja povratna vrijednost metode je popunjena lista.

Vrijednosti u listi su:

  • vrijednost TEC

  • vrijednost REC

  • broj puta koliko je kontroler ušao u stanje Error Warning (vraća se na 0 nakon 65535)

  • broj puta koliko je kontroler ušao u stanje Error Passive (vraća se na 0 nakon 65535)

  • broj puta koliko je kontroler ušao u stanje Bus Off (vraća se na 0 nakon 65535)

  • broj TX poruka na čekanju

  • broj RX poruka na čekanju u fifo 0

  • broj RX poruka na čekanju u fifo 1

setfilter(bank: int, mode: int, fifo: int, params: Tuple[int, ...], *, rtr: Tuple[bool, ...] | None = None, extframe: bool = False) None

Konfigurira banku filtra:

  • bank je banka filtra klasičnog CAN kontrolera ili indeks CAN FD filtra koji se konfigurira.

  • mode je način rada u kojem bi filtar trebao raditi, pogledajte tablice u nastavku.

  • fifo je oznaka u kojem fifo-u (0 ili 1) bi se poruka trebala pohraniti ako je prihvaćena ovim filtrom.

  • params je polje vrijednosti koje definira filtar. Sadržaj polja ovisi o argumentu mode.

Sadržaj polja params za klasične CAN kontrolere (OpenMV Cam M4 / M7):

mode

Sadržaj polja params

CAN.LIST16

Četiri 16-bitna ID-a koja će biti prihvaćena.

CAN.LIST32

Dva 32-bitna ID-a koja će biti prihvaćena.

CAN.MASK16

Dva para 16-bitni id/maska, npr. (1, 3, 4, 4). Prvi par (1, 3) prihvaća sve ID-ove s bitom 0 = 1 i bitom 1 = 0; drugi par (4, 4) prihvaća sve ID-ove s bitom 2 = 1.

CAN.MASK32

Jedan par 32-bitni id/maska (inače isto kao CAN.MASK16).

Sadržaj polja params za CAN FD kontrolere (OpenMV Cam H7 / H7 Plus / Pure Thermal):

mode

Sadržaj polja params

CAN.RANGE

Dva ID-a koja tvore raspon prihvaćenih ID-ova.

CAN.DUAL

Dva ID-a koja će biti prihvaćena (npr. (1, 2)).

CAN.MASK

Jedan par (id, mask) (npr. (0x111, 0x7FF)).

  • rtr Za klasične CAN kontrolere, ovo je polje logičkih vrijednosti koje određuje hoće li filtar prihvatiti poruku zahtjeva za udaljeni prijenos. Ako ovaj argument nije zadan, zadana vrijednost je False za sve unose. Duljina ovisi o mode:

    mode

    len(rtr)

    Napomene

    CAN.LIST16

    4

    CAN.LIST32

    2

    CAN.MASK16

    2

    CAN.MASK32

    1

    Za CAN FD ovaj se argument zanemaruje.

  • extframe Ako je True, okvir će imati prošireni identifikator (29 bita), inače se koristi standardni identifikator (11 bita).

clearfilter(bank: int, extframe: bool = False) None

Briše i onemogućuje banku filtra:

  • bank je banka filtra klasičnog CAN kontrolera ili indeks CAN FD filtra koji se briše.

  • extframe Za CAN FD kontrolere, ako je True, briše prošireni filtar (konfiguriran s extframe=True), inače briše standardni identifikator (konfiguriran s extframe=False).

any(fifo: int) bool

Vraća True ako bilo koja poruka čeka na FIFO-u, inače False.

recv(fifo: int, list: list | None = None, *, timeout: int = 5000) list

Prima podatke na sabirnici:

  • fifo je cijeli broj, koji je FIFO na kojem se prima

  • list je opcionalni objekt liste koji se koristi kao povratna vrijednost

  • timeout je vremensko ograničenje u milisekundama za čekanje na primanje.

Povratna vrijednost: lista koja sadrži pet vrijednosti.

  • ID poruke.

  • Logička vrijednost koja označava je li ID poruke standardni ili prošireni.

  • Logička vrijednost koja označava je li poruka RTR poruka.

  • Vrijednost FMI (Filter Match Index).

  • Polje koje sadrži podatke.

Ako je list jednak None, tada će se alocirati nova lista, kao i novi bytes objekt za sadržavanje podataka (kao peti element u listi).

Ako list nije None, tada bi to trebao biti objekt liste s najmanje pet elemenata. Peti element trebao bi biti memoryview objekt koji je stvoren ili iz bytearray ili iz polja tipa ‘B’ ili ‘b’, a to polje mora imati dovoljno prostora za najmanje 8 bajtova. Objekt liste tada će biti popunjen s prve četiri gore navedene povratne vrijednosti, a memoryview objekt bit će promijenjen na mjestu na veličinu podataka i popunjen tim podacima. Isti objekti liste i memoryview mogu se ponovno koristiti u kasnijim pozivima ove metode, što pruža način primanja podataka bez korištenja hrpe. Na primjer:

buf = bytearray(8)
lst = [0, 0, 0, 0, memoryview(buf)]
# No heap memory is allocated in the following call
can.recv(0, lst)
send(data: int | bytes | bytearray, id: int, *, timeout: int = 0, rtr: bool = False, extframe: bool = False, fdf: bool = False, brs: bool = False) None

Šalje poruku na sabirnici:

  • data su podaci za slanje (cijeli broj za slanje ili buffer objekt).

  • id je ID poruke koja se šalje.

  • timeout je vremensko ograničenje u milisekundama za čekanje na slanje.

  • rtr je logička vrijednost koja određuje hoće li se poruka poslati kao zahtjev za udaljeni prijenos. Ako je rtr True, tada se samo duljina data koristi za popunjavanje DLC mjesta okvira; stvarni bajtovi u data se ne koriste.

  • extframe ako je True, okvir će imati prošireni identifikator (29 bita), inače se koristi standardni identifikator (11 bita).

  • fdf za CAN FD kontrolere, ako je postavljen na True, okvir će imati FD format okvira, koji podržava podatkovne sadržaje do 64 bajta.

  • brs za CAN FD kontrolere, ako je postavljen na True, omogućen je način prebacivanja brzine prijenosa, u kojem se podatkovna faza prenosi različitom brzinom prijenosa. Pogledajte CAN.init() za parametre konfiguracije vremena podatkovnog bita.

Ako je timeout 0, poruka se smješta u jedan od tri hardverska međuspremnika i metoda se odmah vraća. Ako su sva tri međuspremnika u upotrebi, baca se iznimka. Ako timeout nije 0, metoda čeka dok se poruka ne prenese. Ako se poruka ne može prenijeti unutar navedenog vremena, baca se iznimka.

Povratna vrijednost: None.

rxcallback(fifo: int, fun: Callable[[CAN, int], None] | None) None

Registrira funkciju koja se poziva kada se poruka prihvati u prazan FIFO:

  • fifo je primajući FIFO.

  • fun je funkcija koja se poziva kada FIFO postane neprazan.

Funkcija povratnog poziva prima dva argumenta: prvi je sam CAN objekt; drugi je cijeli broj koji označava razlog za povratni poziv:

Razlog

Značenje

0

Poruka je prihvaćena u prazan FIFO.

1

FIFO je pun.

2

Poruka je izgubljena zbog punog FIFO-a.

Primjer korištenja rxcallback:

def cb0(bus, reason):
  print('cb0')
  if reason == 0:
      print('pending')
  if reason == 1:
      print('full')
  if reason == 2:
      print('overflow')

can = CAN(1, CAN.LOOPBACK)
can.rxcallback(0, cb0)

Konstante

Konstante načina rada sabirnice (argument mode za init()):

NORMAL: int

Kontroler normalno sudjeluje na sabirnici – prenosi vlastite okvire i potvrđuje valjane primljene okvire.

LOOPBACK: int

Interni petljani (loopback) način rada: kontroler je odspojen od pinova i preusmjerava prenesene okvire izravno natrag na put primanja. Korisno za samotestiranje bez primopredajnika.

SILENT: int

Način rada samo za slušanje: kontroler prima okvire, ali nikad ne pogoni sabirnicu (nema ACK-a, nema prijenosa). Korisno za prisluškivanje sabirnice.

SILENT_LOOPBACK: int

Kombinira SILENT i LOOPBACK: nema aktivnosti na pinovima i nema potvrda, uz internu petlju TX-a u RX.

Konstante stanja kontrolera (vraća ih state()):

STOPPED: int

Kontroler je potpuno isključen i resetiran.

ERROR_ACTIVE: int

Kontroler je uključen i u stanju Error Active (i TEC i REC su manji od 96).

ERROR_WARNING: int

Kontroler je uključen i u stanju Error Warning (barem jedan od TEC ili REC je 96 ili veći).

ERROR_PASSIVE: int

Kontroler je uključen i u stanju Error Passive (barem jedan od TEC ili REC je 128 ili veći).

BUS_OFF: int

Kontroler je uključen, ali ne sudjeluje u aktivnosti sabirnice (TEC je prešao 255).

Načini rada filtra klasičnog CAN-a (argument mode za setfilter() na OpenMV Cam M4 / M7):

LIST16: int

Polje filtra params sadrži četiri 16-bitna ID-a koja će biti prihvaćena.

LIST32: int

Polje filtra params sadrži dva 32-bitna ID-a koja će biti prihvaćena.

MASK16: int

Polje filtra params sadrži dva 16-bitna para (id, mask).

MASK32: int

Polje filtra params sadrži jedan 32-bitni par (id, mask).

Načini rada CAN FD filtra (argument mode za setfilter() na OpenMV Cam H7 / H7 Plus / Pure Thermal):

RANGE: int

Polje filtra params sadrži dva ID-a koja tvore raspon prihvaćenih ID-ova.

DUAL: int

Polje filtra params sadrži dva specifična ID-a za prihvaćanje.

MASK: int

Polje filtra params sadrži jedan par (id, mask).