class CAN – Controller Area Network-protocol

CAN is een tweedraads serieel protocol dat wordt gebruikt voor betrouwbare realtime-berichtbezorging tussen een of meer nodes die op een gemeenschappelijke bus zijn aangesloten. CAN 2.0 is gestandaardiseerd in ISO-11898 en staat nu ook bekend als CAN Classic.

Er bestaat ook een nieuwer, achterwaarts compatibel protocol genaamd CAN FD (CAN with Flexible Data-Rate). De machine.CAN-driver ondersteunt momenteel geen CAN FD-functies; gebruik pyb.CAN op STM32 als je CAN FD nodig hebt.

CAN-ondersteuning vereist een controller (vaak een intern microcontroller-randapparaat) en een externe transceiver om de signalen op het juiste niveau naar de CAN-bus te brengen.

Beschikbaar op STM32 OpenMV-cams (M4 / M7 / H7 / H7 Plus / Pure Thermal / N6, plus de Arduino-merkvarianten die een transceiver bekabelen). Nog niet ondersteund op de OpenMV Cam RT1062 (mimxrt-port) of de OpenMV Cam AE3 (alif-port).

De machine.CAN-interface is een low-level basis CAN-berichtinterface die een CAN-controller abstraheert als een uitgaande prioriteitswachtrij voor het verzenden van berichten, een inkomende wachtrij voor het ontvangen van berichten, en mechanismen voor het rapporteren van fouten.

Notitie

De geplande micropython-lib-modules can en aiocan worden de aanbevolen manier om CAN te gebruiken met MicroPython.

Constructor

class machine.CAN(id: int, *args, **kwargs)

Construeer een CAN-controllerobject met de gegeven id:

  • id identificeert een bepaald CAN-controllerobject; dit is bord- en port-specifiek.

  • Alle overige argumenten worden doorgegeven aan CAN.init(). Er moet ten minste één argument (bitrate) worden opgegeven.

Toekomstige versies van deze klasse kunnen hier ook port-specifieke keyword-argumenten accepteren die de hardware configureren. Momenteel zijn er geen dergelijke keyword-argumenten geïmplementeerd.

Voorbeeld

Construeer en initialiseer CAN-controller 1 met een bitrate van 500 kbps:

from machine import CAN
can = CAN(1, 500_000)

Methoden

init(bitrate: int, mode: int = CAN.MODE_NORMAL, sample_point: int = 75, sjw: int = 1, tseg1: int | None = None, tseg2: int | None = None) None

Initialiseer de CAN-bus met de gegeven parameters:

  • bitrate is de gewenste bus-bitrate in bits per seconde.

  • mode is een van de waarden die worden getoond onder Modi en geeft de gewenste werkingsmodus aan. De standaardwaarde is “normal”-werking op de bus.

De volgende parameters zijn optioneel en hebben betrekking op CAN-bittimings. In de meeste gevallen kun je deze parameters op de standaardwaarden laten staan:

  • sample_point is een geheeltallig percentage van de databittijd. Het bepaalt de positie van de bitmonstering ten opzichte van de volledige nominale bittijd. De CAN-driver berekent de parameters dienovereenkomstig. Deze parameter wordt genegeerd als tseg1 en tseg2 zijn ingesteld.

  • sjw is de hersynchronisatie-sprongbreedte in eenheden van tijdsquanta voor nominale bits; het kan een waarde zijn tussen 1 en 4 inclusief voor classic CAN.

  • tseg1 bepaalt de locatie van het samplepunt in eenheden van tijdsquanta voor nominale bits; het kan een waarde zijn tussen 1 en 16 inclusief voor classic CAN. Dit is de som van de Prop_Seg- en Phase_Seg1-fasen zoals gedefinieerd in de ISO-11898-standaard. Als deze waarde is ingesteld, moet tseg2 ook worden ingesteld en wordt sample_point genegeerd.

  • tseg2 bepaalt de locatie van het zendpunt in eenheden van tijdsquanta voor nominale bits; het kan een waarde zijn tussen 1 en 8 inclusief voor classic CAN. Dit komt overeen met Phase_Seg2 in de ISO-11898-standaard. Als deze waarde is ingesteld, moet tseg1 ook worden ingesteld.

Als deze argumenten worden opgegeven, wordt de CAN-controller correct geconfigureerd voor de gewenste bitrate en het opgegeven totale aantal tijdsquanta per bit. De waarden tseg1 en tseg2 overschrijven het argument sample_point als alle drie worden opgegeven.

Notitie

Individuele controllerhardware kan aanvullende beperkingen hebben op geldige waarden voor deze parameters en zal een ValueError opwerpen als een bepaalde waarde niet wordt ondersteund.

Notitie

Specifieke controllerhardware kan aanvullende optionele keyword-parameters accepteren voor hardware-specifieke functies zoals oversampling.

set_filters(filters: list | tuple | None) None

Stel ontvangstfilters in de CAN-controller in. filters kan zijn:

  • None om alle inkomende berichten te accepteren, of

  • [] of () om alle berichtontvangst uit te schakelen, of

  • Een iterable met een of meer items die de filtercriteria definiëren. Elk item moet een tuple of lijst met drie elementen zijn:

    • identifier is een CAN-identifier (int).

    • bit_mask is een bitmasker voor bits in het CAN-identifier-veld (int).

    • flags is een integer met nul of meer van de bits die zijn gedefinieerd in Berichtflags. Dit specificeert eigenschappen waaraan het inkomende bericht moet voldoen. Niet alle controllers ondersteunen filtering op alle flags; er wordt een ValueError opgeworpen als een niet-ondersteunde flag wordt aangevraagd.

Inkomende berichten worden geaccepteerd als de bits die in bit_mask zijn gemaskeerd overeenkomen tussen de berichtidentifier en de filterwaarde identifier, en de flags die in het filter zijn ingesteld overeenkomen met het inkomende bericht.

Als de bit CAN.FLAG_EXT_ID is ingesteld in flags, komt het filter alleen overeen met Extended CAN-ID’s. Als de bit CAN.FLAG_EXT_ID niet is ingesteld, komt het filter alleen overeen met Standard CAN-ID’s.

Alle filters worden in de controller met OR samengevoegd. Het doorgeven van een lege lijst of tuple voor het filters-argument betekent dat er geen berichten worden ontvangen.

Sommige CAN-controllers vereisen dat elk filter aan slechts één ontvangst-FIFO wordt gekoppeld. In deze gevallen worden de filteritems in het argument round-robin toegewezen aan de beschikbare FIFO’s. Deze driver maakt geen onderscheid tussen FIFO’s in de ontvangst-IRQ.

Notitie

Als de aanroeper een iterable doorgeeft met meer items dan CAN.FILTERS_MAX, wordt een ValueError opgeworpen.

Notitie

Als ofwel de identifier ofwel de bit_mask buiten bereik is voor het opgegeven ID-type, wordt een ValueError met als reden “invalid id” opgeworpen.

Voorbeelden

Ontvang alle inkomende berichten:

can.set_filters(None)

Ontvang alleen berichten met Standard ID-waarden 0x301 en 0x700:

can.set_filters(((0x301, 0x7FF, 0),
                 (0x700, 0x7FF, 0)))

Ontvang alleen berichten met Standard ID-waarden in het bereik 0x300-0x3FF en Extended ID-waarde 0x50700:

can.set_filters(((0x300, 0x700, 0),
                 (0x50700, 0x1FFF_FFFF, CAN.FLAG_EXT_ID)))
FILTERS_MAX: int

Constante waarde die het maximale aantal ondersteunde ontvangstfilters voor deze hardwarecontroller uitleest.

Merk op dat sommige controllers complexere hardwarebeperkingen kunnen hebben op het aantal in gebruik zijnde filters (bijvoorbeeld het onafhankelijk tellen van Standard en Extended ID-filters). In deze gevallen kan CAN.set_filters een ValueError opwerpen, zelfs wanneer de FILTERS_MAX-limiet niet wordt overschreden.

send(id: int, data: bytes, flags: int = 0) int | None

Kopieer een nieuw CAN-bericht naar de hardware-zendwachtrij van de controller om op de bus te worden verzonden. De zendwachtrij is een prioriteitswachtrij die is gesorteerd op CAN-identifier-prioriteit (lagere numerieke identifiers hebben een hogere prioriteit).

  • id is een geheeltallige CAN-identifier-waarde.

  • data is een bytes-object (of vergelijkbaar) dat de CAN-berichtgegevens bevat, of dat een Remote Transmission Request beschrijft (zie hieronder).

  • flags is een integer met nul of meer van de bits die zijn gedefinieerd in Berichtflags, die eigenschappen van het uitgaande CAN-bericht specificeert (Extended ID, Remote Transmission Request, enz.)

Als het bericht succesvol in de wachtrij is geplaatst voor verzending op de bus, retourneert de functie een integer in het bereik 0 tot CAN.TX_QUEUE_LEN (exclusief). Deze waarde is de zendbufferindex waar het bericht in de wachtrij staat om te verzenden, en kan worden gebruikt door de functie CAN.cancel_send en in CAN.IRQ_TX-events.

Als de wachtrij vol is, mislukt de verzending en wordt None geretourneerd.

De verzending kan ook mislukken en None retourneren als de opgegeven id-waarde dezelfde prioriteit heeft als een bestaand bericht in de zendwachtrij en de CAN-controllerhardware niet kan garanderen dat berichten met dezelfde ID in dezelfde volgorde op de bus worden verzonden als waarin ze aan de wachtrij zijn toegevoegd. Geef de flag CAN.FLAG_UNORDERED door in het flags-argument om het bericht toch in de wachtrij te plaatsen. Deze flag geeft aan dat het OK is om berichten met dezelfde CAN-ID in willekeurige volgorde op de bus te verzenden.

Als de controller zich in de “Bus Off”-foutstatus bevindt of is uitgeschakeld, werpt het aanroepen van deze functie een OSError op.

Notitie

Deze opzettelijk low-level implementatie is zo ontworpen dat de aanroeper een softwarematige wachtrij van uitgaande berichten kan opzetten.

Belangrijk

De CAN-“zendwachtrij” is geen FIFO-wachtrij, maar is op prioriteit geordend, en hoewel deze tot CAN.TX_QUEUE_LEN items kan bevatten, kunnen er andere hardwarebeperkingen gelden voor berichten die tegelijkertijd in de wachtrij kunnen worden geplaatst.

Remote Transmission Requests

Als de bit CAN.FLAG_RTR is ingesteld in het flags-argument, verzendt de controller een Remote Transmission Request in plaats van een bericht. In dat geval wordt de inhoud van het data-argument genegeerd. De controller verzendt een verzoek waarbij het lengteveld DLC gelijk is aan de lengte van het data-argument.

Voorbeelden

Probeer een bericht te verzenden met een payload van drie bytes 0a0b0c en Standard ID 0x200:

can.send(0x200, b"\x0a\x0b\x0c", 0)

Probeer een bericht te verzenden met een lege payload en Extended ID 0x180008. Geef aan dat de controller berichten met deze ID in willekeurige volgorde mag verzenden, voor het geval er al andere berichten met dezelfde ID in de wachtrij staan om te verzenden:

can.send(0x180008, b"", can.FLAG_EXT_ID | can.FLAG_UNORDERED)

Probeer een Remote Transmission Request met lengte 8 bytes en Standard ID 0x555 te verzenden:

can.send(0x555, b" " * 8, can.FLAG_RTR)
recv(arg: list | None = None) list | None

Retourneer een CAN-bericht dat door de controller is ontvangen, conform de filters die zijn ingesteld door CAN.set_filters().

Deze functie neemt één optioneel argument; indien opgegeven moet het een lijst van ten minste 4 elementen zijn waarbij het tweede element een memoryview-object is dat verwijst naar een bytearray of vergelijkbaar object met voldoende capaciteit om elk ontvangen CAN-bericht te bevatten (8 bytes voor CAN Classic, 64 bytes voor CAN FD). De opgegeven lijst wordt geretourneerd als een succesvol resultaat en voorkomt geheugenallocatie binnen de functie.

Als de CAN-controller geen berichten heeft ontvangen, retourneert deze functie None.

Notitie

CAN.set_filters moet worden aangeroepen voordat de controller berichten kan ontvangen. Roep set_filters(None) aan om alle berichten te ontvangen.

Als de CAN-controller een bericht heeft ontvangen, retourneert deze functie een lijst met 4 elementen:

  • Index 0 is de CAN-ID van het ontvangen bericht, als een integer.

  • Index 1 is een memoryview die toegang biedt tot de ontvangen berichtgegevens.

    • Als arg niet wordt opgegeven, is dit een memoryview die de ontvangen bytes bevat. Deze memoryview wordt ondersteund door een nieuw gealloceerde bytearray die groot genoeg is om elk ontvangen CAN-bericht te bevatten. Hierdoor kan het resultaat veilig worden hergebruikt als een toekomstige arg, om geheugenallocaties te besparen.

    • Als arg wordt opgegeven, wordt de opgegeven memoryview verkleind om precies de ontvangen bytes te bevatten. De aanroeper is verantwoordelijk om ervoor te zorgen dat het onderliggende object voor de memoryview een CAN-bericht van elke lengte kan bevatten.

  • Index 2 is een integer met nul of meer van de bits die zijn gedefinieerd in Berichtflags. Het geeft metadata over het ontvangen bericht aan.

  • Index 3 is een integer met nul of meer van de bits die zijn gedefinieerd in Ontvangstfoutflags. Elke waarde die niet nul is, duidt op mogelijke problemen bij het ontvangen van CAN-berichten. Deze flags worden binnen de controller gereset telkens wanneer deze functie terugkeert.

Remote Transmission Requests

Als een Remote Transmission Request wordt ontvangen, wordt de bit CAN.FLAG_RTR ingesteld in Index 2 en bevat de memoryview op Index 1 allemaal nullen, met een lengte gelijk aan het DLC-veld van het ontvangen verzoek.

Voorbeeld
can.set_filters(None)   # receive all
while True:
    res = can.recv()
    if res:
        can_id, data, flags, errs = res
        print("Received", hex(can_id), data.hex(), hex(flags), hex(errs))
    else:
        time.sleep_ms(1)  # not a good pattern, use the irq instead!
irq(handler: Callable[[CAN], None] | None = None, trigger: int = 0, hard: bool = False) None

Stelt een interrupt-handler-functie in die wordt aangeroepen wanneer een of meer van de in trigger gemarkeerde events is opgetreden.

  • handler is een functie die wordt aangeroepen wanneer het interrupt-event afgaat. De handler moet precies één argument aannemen, namelijk de CAN-instantie.

  • trigger configureert het/de event(s) die een interrupt kunnen genereren. Mogelijke waarden zijn een masker van een of meer van het volgende:

    • Het event CAN.IRQ_RX treedt op nadat de CAN-controller ten minste één bericht in zijn RX-FIFO heeft ontvangen (wat betekent dat CAN.recv() succesvol zal terugkeren).

    • Het event CAN.IRQ_TX treedt op nadat de CAN-controller een bericht ofwel succesvol op de CAN-bus heeft verzonden ofwel een bericht niet heeft kunnen verzenden. Deze trigger heeft aanvullende vereisten voor de handler, zie IRQ-flags voor details.

    • Het event CAN.IRQ_STATE treedt op wanneer de CAN-controller is overgegaan naar een ernstigere foutstatus. Roep CAN.state() aan om de bijgewerkte status te verkrijgen.

  • hard als True wordt een hard interrupt gebruikt. Dit vermindert de vertraging tussen het CAN-controllerevent en het aanroepen van de handler. Hard interrupt-handlers mogen geen geheugen alloceren; zie Interrupt-handlers schrijven.

Retourneert een irq-object. Indien aangeroepen zonder argumenten wordt een eerder geconfigureerd irq-object geretourneerd.

Zie IRQ-flags voor een voorbeeld.

cancel_send(index: int) bool

Verzoek de CAN-controller om het verzenden van een bericht op de bus te annuleren.

Het argument index identificeert een enkele zendbuffer. Het moet een integer zijn in het bereik 0 tot CAN.TX_QUEUE_LEN (exclusief). Doorgaans is dit een waarde die eerder is geretourneerd door CAN.send().

Het resultaat is True als er in deze buffer een bericht in afwachting van verzending stond en de verzending is geannuleerd.

Het resultaat is anders False (ofwel stond er geen bericht in afwachting van verzending in deze buffer, ofwel is de verzending al gelukt).

Het IRQ-event CAN.IRQ_TX moet worden gebruikt om te bepalen of een bericht zeker is verzonden of niet, maar merk op dat er mogelijke race-condities zijn als een verzending wordt geannuleerd en vervolgens dezelfde buffer wordt gebruikt om een ander bericht te verzenden (vooral als de CAN-controller-IRQ niet “hard” is).

state() int

Retourneert een geheeltallige waarde die de huidige status van de controller aangeeft. De waarde is een van de waarden die zijn gedefinieerd in Statussen.

Foutstatussen van lagere ernst kunnen automatisch worden gewist als de bus herstelt, maar de status CAN.STATE_BUS_OFF kan alleen worden hersteld door CAN.restart() aan te roepen.

get_counters(list: list | None = None, /) list

Retourneert de foutteller-waarden van de controller. Het resultaat is een lijst van acht waarden. Als de optionele parameter list wordt opgegeven, wordt het opgegeven lijstobject bijgewerkt en als resultaat geretourneerd, om een allocatie te vermijden.

De lijstitems zijn:

  • TEC-waarde (Transmit Error Counter)

  • REC-waarde (Receive Error Counter)

  • Aantal keren dat de controller vanuit de Active-status in de Warning-status is gegaan.

  • Aantal keren dat de controller vanuit de Warning-status in de Error Passive-status is gegaan.

  • Aantal keren dat de controller vanuit de Error Passive-status in de Bus Off-status is gegaan.

  • Totaal aantal in afwachting zijnde TX-berichten in de hardwarewachtrij.

  • Totaal aantal in afwachting zijnde RX-berichten in de hardwarewachtrij.

  • Aantal keren dat een RX-overrun optrad.

Notitie

Afhankelijk van de controller kunnen deze waarden na een bepaalde waarde terugrollen naar 0.

Notitie

Als een controller een bepaalde teller niet ondersteunt, retourneert deze None voor dat lijstelement.

get_timings(list: list | None = None, /) list

Retourneert een lijst van elementen die de huidige timings aangeven die in de CAN-controller zijn geconfigureerd. Dit kan worden gebruikt om timings te verifiëren voor debugdoeleinden. Het resultaat is een lijst van zes waarden. Als de optionele parameter list wordt opgegeven, wordt het opgegeven lijstobject bijgewerkt en als resultaat geretourneerd, om een allocatie te vermijden.

De lijstitems zijn:

  • Exacte bitrate die door de controller wordt gebruikt. Kan afwijken van het bitrate-argument dat aan CAN.init() is doorgegeven vanwege kwantisatie om aan hardwarebeperkingen te voldoen.

  • Hersynchronisatie-sprongbreedte (SJW) in eenheden van tijdsquanta voor nominale bits. Heeft dezelfde betekenis als de parameter sjw van CAN.init().

  • Locatie van het samplepunt in eenheden van tijdsquanta voor nominale bits. Heeft dezelfde betekenis als de parameter tseg1 van CAN.init().

  • Locatie van het zendpunt in eenheden van tijdsquanta voor nominale bits. Heeft dezelfde betekenis als de parameter tseg2 van CAN.init().

  • CAN FD-timinginformatie. None voor controllers die geen CAN FD ondersteunen, of als CAN FD niet is geïnitialiseerd. Anders een geneste lijst van vier elementen die overeenkomen met de bovenstaande items, maar van toepassing zijn op de CAN FD BRS-functie.

  • Optionele controller-specifieke timinginformatie. Afhankelijk van de controller is dit ofwel None als de controller er geen rapporteert, ofwel een lijst van constante lengte waarvan de elementen specifiek zijn voor een bepaalde hardwarecontroller.

Notitie

Als CAN.init() niet is aangeroepen, retourneert deze functie nog steeds een resultaat, maar het resultaat hangt af van de interne werking van de controller en is mogelijk niet nauwkeurig.

restart() None

Zorgt ervoor dat de controller STATE_BUS_OFF verlaat zonder enige andere interne status te wissen. Wist ook enkele van de fouttellers (altijd het aantal keren dat elke foutstatus is binnengegaan, mogelijk TEC en REC afhankelijk van de controller).

Het aanroepen van deze functie annuleert ook eventuele berichten die op verzending wachten. Voor deze berichten worden geen IRQ_TX-interrupts geleverd.

Merk op dat deze functie er mogelijk wel of niet voor zorgt dat de controller de “Error Passive”-status verlaat, afhankelijk van of de controllerhardware TEC en REC op nul zet of niet.

deinit() None

Deïnitialiseert een eerder actieve CAN-instantie. Alle in afwachting zijnde berichten (verzenden en ontvangen) worden verworpen en de controller stopt met interacteren op de bus. Roep CAN.init() aan om deze instantie opnieuw te gebruiken.

Er worden geen IRQ_TX- of IRQ_RX-interrupts aangeroepen als reactie op het aanroepen van deze functie.

Zie ook CAN.restart().

Constanten

TX_QUEUE_LEN: int

Maximaal aantal CAN-berichten dat in de wachtrij van de uitgaande hardwareberichtwachtrij van de controller kan worden geplaatst. De “zendbufferindexen” die worden gebruikt door CAN.send(), CAN.cancel_send() en IRQ-flags vallen binnen dit bereik.

Modi

Deze waarden vertegenwoordigen de werkingsmodi van de controller, zoals doorgegeven aan CAN.init(). Niet alle controllers ondersteunen mogelijk alle modi.

Het wijzigen van de modus van een draaiende controller vereist het aanroepen van CAN.deinit() en vervolgens opnieuw aanroepen van CAN.init() met de nieuwe modus.

MODE_NORMAL: int

De controller is actief als een standaard CAN-netwerknode (zal geldige berichten bevestigen en kan fouten verzenden afhankelijk van zijn huidige Status).

MODE_SLEEP: int

De CAN-controller slaapt in een energiezuinige modus. Afhankelijk van de controller kan dit het wekken van de controller en de overgang naar CAN.MODE_NORMAL ondersteunen als er CAN-verkeer wordt ontvangen.

MODE_LOOPBACK: int

Een testmodus. De CAN-controller is nog steeds verbonden met de externe bus, maar ontvangt ook zijn eigen verzonden berichten en negeert eventuele ACK-fouten.

MODE_SILENT: int

De CAN-controller ontvangt berichten maar interacteert niet met de CAN-bus (inclusief het verzenden van ACK’s, fouten, enz.)

MODE_SILENT_LOOPBACK: int

Een testmodus die helemaal geen aangesloten CAN-transceiver vereist. De CAN-controller ontvangt zijn eigen verzonden berichten zonder enige interactie met de CAN-bus. De CAN TX- en RX-pinnen blijven inactief.

Statussen

Deze waarden worden geretourneerd door CAN.state() en weerspiegelen de foutstatus van de CAN-controller:

STATE_STOPPED: int

De controller is niet geïnitialiseerd.

STATE_ACTIVE: int

De controller is actief en de fouttellers TEC en REC liggen beide onder de waarschuwingsdrempel van 96. Zie CAN.get_counters().

STATE_WARNING: int

De controller is actief maar ten minste een van de fouttellers TEC en REC ligt tussen 96 en 127. Zie CAN.get_counters().

STATE_PASSIVE: int

De controller bevindt zich in de “Error Passive”-status, wat betekent dat hij geen actieve fouten meer naar de bus verzendt, maar verder functioneel is. Deze status wordt binnengegaan wanneer ten minste een van de fouttellers TEC en REC 128 of hoger is, maar TEC minder dan 255 is. Zie CAN.get_counters().

STATE_BUS_OFF: int

De controller bevindt zich in de Bus-Off-status, wat betekent dat de foutteller TEC groter is dan 255. De CAN-controller interacteert in deze status niet met de bus en moet via CAN.restart() opnieuw worden gestart om door te gaan.

Berichtflags

Deze waarden vertegenwoordigen metadata over een CAN-bericht. De functies CAN.send(), CAN.recv() en CAN.set_filters() accepteren of retourneren een geheeltallige waarde die bestaat uit nul of meer van deze flags die met bitwise OR zijn samengevoegd.

FLAG_RTR: int

Geeft aan dat een bericht een remote transmission request is.

FLAG_EXT_ID: int

Indien ingesteld, geeft aan dat een berichtidentifier Extended is (29-bit). Indien niet ingesteld, geeft aan dat een berichtidentifier Standard is (11-bit).

FLAG_UNORDERED: int

Indien ingesteld in het flags-argument van CAN.send(), geeft aan dat het OK is als berichten met dezelfde CAN-ID in willekeurige volgorde op de bus worden verzonden.

Anders kan het proberen om meerdere berichten met dezelfde ID in de wachtrij te plaatsen ertoe leiden dat CAN.send() mislukt als de controllerhardware geen volgorde kan afdwingen.

Deze flag wordt nooit ingesteld op ontvangen berichten en wordt genegeerd door CAN.set_filters().

Ontvangstfoutflags

Het resultaat van CAN.recv() bevat een geheeltallige waarde die bestaat uit nul of meer van deze flags die met bitwise OR zijn samengevoegd. Indien ingesteld, duiden deze flags op mogelijke algemene problemen bij het ontvangen van CAN-berichten.

RECV_ERR_FULL: int

De hardware-FIFO waar dit bericht is ontvangen is vol en aanvullende inkomende berichten kunnen verloren gaan.

RECV_ERR_OVERRUN: int

De hardware-FIFO waar dit bericht is ontvangen is vol en een of meer inkomende berichten zijn verloren gegaan.

IRQ-waarden

IRQ_RX: int

Geef door aan het argument trigger van irq() om de handler af te laten gaan telkens wanneer de CAN-controller een volledig bericht in de RX-FIFO heeft ontvangen. Lees binnen de handler het bericht met recv().

IRQ_TX: int

Geef door aan het argument trigger van irq() om de handler af te laten gaan telkens wanneer de CAN-controller een zendpoging voltooit (succes of mislukking). Gebruik binnen de handler de aanvullende bits hieronder om te achterhalen welke mailbox is voltooid en of deze is mislukt – zie IRQ-flags.

IRQ_STATE: int

Geef door aan het argument trigger van irq() om de handler af te laten gaan telkens wanneer de controller overgaat tussen de STATE_*-waarden (active / warning / passive / bus-off). Gebruik state() binnen de handler om de nieuwe status te lezen.

IRQ_TX_FAILED: int

Statusflag die kan worden ingesteld in irq().flags() wanneer een IRQ_TX-event afgaat. Geeft aan dat de zendpoging is mislukt (meestal omdat cancel_send() is aangeroepen, of de controller in een foutstatus is gegaan).

IRQ_TX_IDX_SHIFT: int

Bitpositie van het transmit-mailbox-index-veld binnen de irq().flags()-waarde tijdens een IRQ_TX-event. De mailbox-index wordt geëxtraheerd als (flags >> IRQ_TX_IDX_SHIFT) & IRQ_TX_IDX_MASK.

IRQ_TX_IDX_MASK: int

Bitmasker van het transmit-mailbox-index-veld binnen de irq().flags()-waarde tijdens een IRQ_TX-event. De geëxtraheerde index komt overeen met de integer die wordt geretourneerd door de bijbehorende send()-aanroep (een int in het bereik 0 tot TX_QUEUE_LEN).

IRQ-flags

Het aanroepen van CAN.irq() registreert een interrupt-handler met een of meer van de triggers CAN.IRQ_RX, CAN.IRQ_TX en CAN.IRQ_STATE.

De functie retourneert een IRQ-object, en het aanroepen van de functie flags() op dit object retourneert een integer die aangeeft welk(e) trigger-event(s) de interrupt hebben veroorzaakt. Een CAN-IRQ-handler moet de functie flags() herhaaldelijk aanroepen totdat deze 0 retourneert.

Wanneer de functie flags() terugkeert met de bit CAN.IRQ_TX ingesteld, kan de handler ook de volgende flag-bits in het resultaat controleren voor aanvullende informatie over het TX-event:

  • De bit CAN.IRQ_TX_FAILED is ingesteld als de verzending is mislukt. Meestal gebeurt dit alleen als CAN.cancel_send() is aangeroepen, hoewel het ook kan gebeuren als de controller in een foutstatus gaat.

  • CAN.IRQ_TX_IDX_MASK << CAN.IRQ_TX_IDX_SHIFT is een met bitmasker afgebakend gebied van de flags-waarde dat de index bevat van de zendbuffer die het event heeft gegenereerd. Dit is een integer in het bereik 0 tot CAN.TX_QUEUE_LEN (exclusief) en komt overeen met het resultaat van een eerdere aanroep van CAN.send().

IRQ_TX-voorbeeld

from machine import CAN

def irq_send(can):
    while flags := can.irq().flags():
        if flags & can.IRQ_TX:
            idx = (flags >> can.IRQ_TX_IDX_SHIFT) & can.IRQ_TX_IDX_MASK
            success = not (flags & can.IRQ_TX_FAILED)
            print("irq_send", idx, success)

can = CAN(1, 500_000)
can.irq(irq_send, trigger=can.IRQ_TX, hard=True)

Belangrijk

Als de trigger CAN.IRQ_TX is ingesteld, moet de handler flags() herhaaldelijk aanroepen totdat deze 0 retourneert, zoals getoond in dit voorbeeld. Anders worden CAN-interrupts mogelijk niet correct opnieuw ingeschakeld.