třída CAN – komunikační sběrnice controller area network

CAN poskytuje podporu jak pro klasický CAN (bxCAN, používaný na OpenMV Cam M4 a M7), tak pro CAN FD (FDCAN, používaný na OpenMV Cam H7, H7 Plus a Pure Thermal) řadičích. Na fyzické úrovni se sběrnice CAN skládá ze dvou vodičů, RX a TX. Pro připojení OpenMV Cam ke sběrnici CAN musíte použít CAN transceiver, který převede logické signály CAN z MCU na správné napěťové úrovně na sběrnici.

Klasický CAN ve smyčkovém režimu (bez transceiveru):

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 se všemi povolenými volitelnými funkcemi (FD rámec, přepínání přenosové rychlosti, rozšířená ID rámců; arbitrážní fáze 500 kbit/s, datová fáze 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)

Následující funkce modulu CAN a jejich argumenty jsou dostupné jak pro klasické, tak pro FD CAN řadiče, pokud není uvedeno jinak.

Konstruktory

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

Vytvoří objekt CAN na dané bus (celočíselný index periferie, např. 1 pro CAN1, 2 pro CAN2). Bez dalších parametrů je objekt vytvořen, ale neinicializován (zachová si předchozí nastavení sběrnice, pokud nějaké existuje); pokud jsou zadány další argumenty, sběrnice se inicializuje. Dostupné parametry naleznete v CAN.init().

CAN(2) je zapojen na stejné piny konektoru na každé OpenMV Cam, která vystavuje pyb.CAN (M4 / M7 / H7 / H7 Plus / Pure Thermal):

Signál

Pin konektoru

Poznámky

RX

P3

TX

P2

Periferie CAN poskytuje pouze signály na logické úrovni; pro řízení skutečné sběrnice CAN je vyžadován externí CAN transceiver.

pyb.CAN není dostupný na OpenMV Cam N6.

Metody

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

Inicializuje sběrnici CAN s danými parametry:

  • mode je jeden z: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK

  • prescaler je hodnota, kterou se dělí vstupní hodinový signál CAN pro generování nominálních časových kvant bitu. Předdělička může být hodnota mezi 1 a 1024 včetně pro klasický CAN a mezi 1 a 512 včetně pro CAN FD.

  • sjw je šířka resynchronizačního skoku v jednotkách časových kvant pro nominální bity; může to být hodnota mezi 1 a 4 včetně pro klasický CAN a mezi 1 a 128 včetně pro CAN FD.

  • bs1 definuje umístění vzorkovacího bodu v jednotkách časových kvant pro nominální bity; může to být hodnota mezi 1 a 16 včetně pro klasický CAN a mezi 2 a 256 včetně pro CAN FD.

  • bs2 definuje umístění vysílacího bodu v jednotkách časových kvant pro nominální bity; může to být hodnota mezi 1 a 8 včetně pro klasický CAN a mezi 2 a 128 včetně pro CAN FD.

  • auto_restart nastavuje, zda se řadič automaticky pokusí obnovit komunikaci po vstupu do stavu bus-off; pokud je toto vypnuto, lze pro opuštění stavu bus-off použít restart()

  • baudrate pokud je zadána přenosová rychlost jiná než 0, tato funkce se pokusí automaticky vypočítat nominální čas bitu CAN (přepisující prescaler, bs1 a bs2), který splňuje jak baudrate (s přesností do 0,1 %), tak požadovaný sample_point (s přesností na nejbližší 1 %). Pro přesnější kontrolu nad časováním CAN nastavte parametry prescaler, bs1 a bs2 přímo.

  • sample_point určuje pozici vzorkování bitu vzhledem k celému nominálnímu času bitu, vyjádřenou jako celočíselné procento nominálního času bitu. Výchozí sample_point je 75 %. Tento parametr je ignorován, pokud není nastaveno baudrate.

  • num_filter_banks pro klasický CAN je to počet bank, které budou přiřazeny k CAN(1), zbytek z 28 je přiřazen k CAN(2).

Zbývající parametry jsou přítomny pouze na deskách s podporou CAN FD a konfigurují volitelnou funkci CAN FD Bit Rate Switch (BRS):

  • brs_prescaler je hodnota, kterou se dělí vstupní hodinový signál CAN FD pro generování časových kvant datového bitu. Předdělička může být hodnota mezi 1 a 32 včetně.

  • brs_sjw je šířka resynchronizačního skoku v jednotkách časových kvant pro datové bity; může to být hodnota mezi 1 a 16 včetně

  • brs_bs1 definuje umístění vzorkovacího bodu v jednotkách časových kvant pro datové bity; může to být hodnota mezi 1 a 32 včetně

  • brs_bs2 definuje umístění vysílacího bodu v jednotkách časových kvant pro datové bity; může to být hodnota mezi 1 a 16 včetně

  • brs_baudrate pokud je zadána přenosová rychlost jiná než 0, tato funkce se pokusí automaticky vypočítat čas datového bitu CAN (přepisující brs_prescaler, brs_bs1 a brs_bs2), který splňuje jak brs_baudrate (s přesností do 0,1 %), tak požadovaný brs_sample_point (s přesností na nejbližší 1 %). Pro přesnější kontrolu nad časováním BRS nastavte parametry brs_prescaler, brs_bs1 a brs_bs2 přímo.

  • brs_sample_point určuje pozici vzorkování bitu vzhledem k celému nominálnímu času bitu, vyjádřenou jako celočíselné procento nominálního času bitu. Výchozí brs_sample_point je 75 %. Tento parametr je ignorován, pokud není nastaveno brs_baudrate.

Časové kvantum tq je základní jednotkou času pro sběrnici CAN. tq je hodnota předděličky CAN dělená PCLK1 (frekvencí interní periferní sběrnice 1); pro zjištění PCLK1 viz pyb.freq().

Jediný bit se skládá ze synchronizačního segmentu, který je vždy 1 tq. Poté následuje bitový segment 1 a poté bitový segment 2. Vzorkovací bod je po skončení bitového segmentu 1. Vysílací bod je po skončení bitového segmentu 2. Přenosová rychlost bude 1/bittime, kde bittime je 1 + BS1 + BS2 vynásobeno časovým kvantem tq.

Například na OpenMV Cam H7 (PCLK1 = 100 MHz) lze CAN 250 kbps s 75% vzorkovacím bodem nakonfigurovat jako prescaler=25, sjw=1, bs1=11, bs2=4: tq = 25 / 100 MHz = 250 ns, bittime = (1 + 11 + 4) × 250 ns = 4 µs, vzorkovací bod = (1 + 11) / 16 = 75% a přenosová rychlost je 1 / 4 µs = 250 kHz.

Více podrobností naleznete v sekci bxCAN / FDCAN referenční příručky STM32 pro MCU vaší OpenMV Cam.

deinit() None

Vypne sběrnici CAN.

restart() None

Vynutí softwarový restart řadiče CAN bez resetování jeho konfigurace.

Pokud řadič vstoupí do stavu bus-off, přestane se účastnit aktivity na sběrnici. Pokud řadič není nakonfigurován pro automatický restart (viz init()), lze tuto metodu použít ke spuštění restartu a řadič bude podle protokolu CAN postupovat tak, aby opustil stav bus-off a přešel do stavu error active.

state() int

Vrátí stav řadiče. Návratová hodnota může být jedna z:

  • CAN.STOPPED – řadič je zcela vypnutý a resetovaný;

  • CAN.ERROR_ACTIVE – řadič je zapnutý a ve stavu Error Active (TEC i REC jsou menší než 96);

  • CAN.ERROR_WARNING – řadič je zapnutý a ve stavu Error Warning (alespoň jeden z TEC nebo REC je 96 nebo větší);

  • CAN.ERROR_PASSIVE – řadič je zapnutý a ve stavu Error Passive (alespoň jeden z TEC nebo REC je 128 nebo větší);

  • CAN.BUS_OFF – řadič je zapnutý, ale neúčastní se aktivity na sběrnici (TEC přetekl nad 255).

info(list: list | None = None) list

Získá informace o chybových stavech řadiče a TX a RX bufferech. Pokud je zadán list, mělo by to být seznamový objekt s alespoň 8 položkami, které budou vyplněny informacemi. Jinak bude vytvořen a vyplněn nový seznam. V obou případech je návratovou hodnotou metody vyplněný seznam.

Hodnoty v seznamu jsou:

  • hodnota TEC

  • hodnota REC

  • počet, kolikrát řadič vstoupil do stavu Error Warning (po dosažení 65535 se vrací na 0)

  • počet, kolikrát řadič vstoupil do stavu Error Passive (po dosažení 65535 se vrací na 0)

  • počet, kolikrát řadič vstoupil do stavu Bus Off (po dosažení 65535 se vrací na 0)

  • počet čekajících TX zpráv

  • počet čekajících RX zpráv na fifo 0

  • počet čekajících RX zpráv na fifo 1

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

Nakonfiguruje filtrovací banku:

  • bank je filtrovací banka klasického CAN řadiče nebo index filtru CAN FD, který se má nakonfigurovat.

  • mode je režim, ve kterém má filtr pracovat, viz tabulky níže.

  • fifo je to, do které fifo (0 nebo 1) má být zpráva uložena, pokud je tímto filtrem přijata.

  • params je pole hodnot, které definuje filtr. Obsah pole závisí na argumentu mode.

Obsah pole params pro klasické CAN řadiče (OpenMV Cam M4 / M7):

mode

Obsah params

CAN.LIST16

Čtyři 16bitová ID, která budou přijata.

CAN.LIST32

Dvě 32bitová ID, která budou přijata.

CAN.MASK16

Dvě dvojice 16bitového id/masky, např. (1, 3, 4, 4). První dvojice (1, 3) přijímá všechna ID s bitem 0 = 1 a bitem 1 = 0; druhá dvojice (4, 4) přijímá všechna ID s bitem 2 = 1.

CAN.MASK32

Jedna dvojice 32bitového id/masky (jinak stejné jako CAN.MASK16).

Obsah pole params pro CAN FD řadiče (OpenMV Cam H7 / H7 Plus / Pure Thermal):

mode

Obsah params

CAN.RANGE

Dvě ID tvořící rozsah přijímaných ID.

CAN.DUAL

Dvě ID, která budou přijata (např. (1, 2)).

CAN.MASK

Jedna dvojice (id, mask) (např. (0x111, 0x7FF)).

  • rtr Pro klasické CAN řadiče je to pole booleovských hodnot, které určuje, zda má filtr přijímat zprávu typu remote transmission request. Pokud tento argument není zadán, je výchozí hodnota False pro všechny položky. Délka závisí na mode:

    mode

    len(rtr)

    Poznámky

    CAN.LIST16

    4

    CAN.LIST32

    2

    CAN.MASK16

    2

    CAN.MASK32

    1

    Pro CAN FD je tento argument ignorován.

  • extframe Pokud je True, rámec bude mít rozšířený identifikátor (29 bitů), jinak se použije standardní identifikátor (11 bitů).

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

Vymaže a zakáže filtrovací banku:

  • bank je filtrovací banka klasického CAN řadiče nebo index filtru CAN FD, který se má vymazat.

  • extframe Pro CAN FD řadiče: pokud je True, vymaže rozšířený filtr (nakonfigurovaný s extframe=True), jinak vymaže standardní identifikátor (nakonfigurovaný s extframe=False).

any(fifo: int) bool

Vrátí True, pokud nějaká zpráva čeká na FIFO, jinak False.

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

Přijme data na sběrnici:

  • fifo je celé číslo, které je FIFO, na které se má přijímat

  • list je volitelný seznamový objekt, který se použije jako návratová hodnota

  • timeout je časový limit v milisekundách, po který se čeká na příjem.

Návratová hodnota: Seznam obsahující pět hodnot.

  • ID zprávy.

  • Booleovská hodnota, která udává, zda je ID zprávy standardní nebo rozšířené.

  • Booleovská hodnota, která udává, zda je zpráva typu RTR.

  • Hodnota FMI (Filter Match Index).

  • Pole obsahující data.

Pokud je list None, alokuje se nový seznam i nový objekt bytes obsahující data (jako pátý prvek seznamu).

Pokud list není None, mělo by to být seznamový objekt s alespoň pěti prvky. Pátý prvek by měl být objekt memoryview vytvořený buď z bytearray, nebo z pole typu ‚B‘ nebo ‚b‘, a toto pole musí mít dostatek místa alespoň pro 8 bajtů. Seznamový objekt pak bude vyplněn prvními čtyřmi výše uvedenými návratovými hodnotami a objekt memoryview bude na místě změněn na velikost dat a vyplněn těmito daty. Stejné objekty list a memoryview lze znovu použít v následných voláních této metody, což poskytuje způsob příjmu dat bez použití haldy. Například:

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

Odešle zprávu na sběrnici:

  • data jsou data k odeslání (celé číslo k odeslání nebo objekt typu buffer).

  • id je id zprávy, která se má odeslat.

  • timeout je časový limit v milisekundách, po který se čeká na odeslání.

  • rtr je booleovská hodnota, která určuje, zda má být zpráva odeslána jako remote transmission request. Pokud je rtr True, použije se pouze délka data k vyplnění slotu DLC rámce; samotné bajty v data se nepoužijí.

  • extframe pokud je True, rámec bude mít rozšířený identifikátor (29 bitů), jinak se použije standardní identifikátor (11 bitů).

  • fdf pro CAN FD řadiče: pokud je nastaveno na True, rámec bude mít formát FD rámce, který podporuje datové užitečné zatížení až 64 bajtů.

  • brs pro CAN FD řadiče: pokud je nastaveno na True, je povolen režim přepínání přenosové rychlosti, ve kterém je datová fáze přenášena jinou přenosovou rychlostí. Konfigurační parametry časování datového bitu naleznete v CAN.init().

Pokud je timeout 0, zpráva se umístí do jednoho ze tří hardwarových bufferů a metoda se okamžitě vrátí. Pokud jsou všechny tři buffery používány, vyvolá se výjimka. Pokud timeout není 0, metoda čeká, dokud se zpráva nepřenese. Pokud zprávu nelze přenést v zadaném čase, vyvolá se výjimka.

Návratová hodnota: None.

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

Zaregistruje funkci, která bude zavolána, když je zpráva přijata do prázdné FIFO:

  • fifo je přijímací FIFO.

  • fun je funkce, která bude zavolána, když se FIFO stane neprázdnou.

Funkce callback přijímá dva argumenty: prvním je samotný objekt CAN; druhým je celé číslo, které udává důvod callbacku:

Důvod

Význam

0

Zpráva byla přijata do prázdné FIFO.

1

FIFO je plná.

2

Zpráva byla ztracena kvůli plné FIFO.

Příklad použití 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)

Konstanty

Konstanty režimu sběrnice (argument mode metody init()):

NORMAL: int

Řadič se normálně účastní na sběrnici – vysílá vlastní rámce a potvrzuje platné přijaté rámce.

LOOPBACK: int

Interní smyčkový režim: řadič je odpojen od pinů a směruje vysílané rámce přímo zpět do přijímací cesty. Užitečné pro autodiagnostiku bez transceiveru.

SILENT: int

Režim pouze pro poslech: řadič přijímá rámce, ale nikdy neřídí sběrnici (žádné ACK, žádné vysílání). Užitečné pro odposlech sběrnice.

SILENT_LOOPBACK: int

Kombinuje SILENT a LOOPBACK: žádná aktivita na pinech a žádná potvrzení, s interní smyčkou TX do RX.

Konstanty stavu řadiče (vracené metodou state()):

STOPPED: int

Řadič je zcela vypnutý a resetovaný.

ERROR_ACTIVE: int

Řadič je zapnutý a ve stavu Error Active (TEC i REC jsou menší než 96).

ERROR_WARNING: int

Řadič je zapnutý a ve stavu Error Warning (alespoň jeden z TEC nebo REC je 96 nebo větší).

ERROR_PASSIVE: int

Řadič je zapnutý a ve stavu Error Passive (alespoň jeden z TEC nebo REC je 128 nebo větší).

BUS_OFF: int

Řadič je zapnutý, ale neúčastní se aktivity na sběrnici (TEC přetekl nad 255).

Režimy filtru klasického CAN (argument mode metody setfilter() na OpenMV Cam M4 / M7):

LIST16: int

Pole filtru params obsahuje čtyři 16bitová ID, která budou přijata.

LIST32: int

Pole filtru params obsahuje dvě 32bitová ID, která budou přijata.

MASK16: int

Pole filtru params obsahuje dvě 16bitové dvojice (id, mask).

MASK32: int

Pole filtru params obsahuje jednu 32bitovou dvojici (id, mask).

Režimy filtru CAN FD (argument mode metody setfilter() na OpenMV Cam H7 / H7 Plus / Pure Thermal):

RANGE: int

Pole filtru params obsahuje dvě ID tvořící rozsah přijímaných ID.

DUAL: int

Pole filtru params obsahuje dvě konkrétní ID k přijetí.

MASK: int

Pole filtru params obsahuje jednu dvojici (id, mask).