class CAN – bus de communication controller area network

CAN prend en charge à la fois le CAN classique (bxCAN, utilisé sur les OpenMV Cam M4 et M7) et le CAN FD (FDCAN, utilisé sur les OpenMV Cam H7, H7 Plus et Pure Thermal). Au niveau physique, le bus CAN se compose de deux lignes, RX et TX. Pour connecter une OpenMV Cam à un bus CAN, vous devez utiliser un émetteur-récepteur CAN afin de convertir les signaux logiques CAN du microcontrôleur aux niveaux de tension corrects sur le bus.

CAN classique en mode bouclage (sans émetteur-récepteur)

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 avec toutes les fonctionnalités optionnelles activées (trame FD, commutation de débit, identifiants de trame étendus ; phase d’arbitrage à 500 kbit/s, phase de données à 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)

Les fonctions du module CAN suivantes et leurs arguments sont disponibles à la fois pour les contrôleurs CAN classique et FD, sauf indication contraire.

Constructeurs

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

Construit un objet CAN sur le bus donné (un index entier de périphérique, par exemple 1 pour CAN1, 2 pour CAN2). Sans paramètres supplémentaires, l’objet est créé mais non initialisé (il conserve les réglages de bus précédents, le cas échéant) ; si des arguments supplémentaires sont fournis, le bus est initialisé. Voir CAN.init() pour les paramètres disponibles.

CAN(2) est câblé sur les mêmes broches d’en-tête sur chaque OpenMV Cam qui expose pyb.CAN (M4 / M7 / H7 / H7 Plus / Pure Thermal) :

Signal

Broche d’en-tête

Notes

RX

P3

TX

P2

Le périphérique CAN fournit uniquement des signaux de niveau logique ; un émetteur-récepteur CAN externe est requis pour piloter un véritable bus CAN.

pyb.CAN n’est pas disponible sur l’OpenMV Cam N6.

Méthodes

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

Initialise le bus CAN avec les paramètres donnés :

  • mode est l’une des valeurs suivantes : NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK

  • prescaler est la valeur par laquelle l’horloge d’entrée du CAN est divisée pour générer les quanta de temps du bit nominal. Le prédiviseur peut prendre une valeur comprise entre 1 et 1024 inclus pour le CAN classique, et entre 1 et 512 inclus pour le CAN FD.

  • sjw est la largeur de saut de resynchronisation en unités de quanta de temps pour les bits nominaux ; elle peut prendre une valeur comprise entre 1 et 4 inclus pour le CAN classique, et entre 1 et 128 inclus pour le CAN FD.

  • bs1 définit l’emplacement du point d’échantillonnage en unités de quanta de temps pour les bits nominaux ; il peut prendre une valeur comprise entre 1 et 16 inclus pour le CAN classique, et entre 2 et 256 inclus pour le CAN FD.

  • bs2 définit l’emplacement du point de transmission en unités de quanta de temps pour les bits nominaux ; il peut prendre une valeur comprise entre 1 et 8 inclus pour le CAN classique, et entre 2 et 128 inclus pour le CAN FD.

  • auto_restart indique si le contrôleur tentera automatiquement de redémarrer les communications après être entré dans l’état bus-off ; si cette option est désactivée, restart() peut être utilisée pour quitter l’état bus-off

  • baudrate si un débit en bauds différent de 0 est fourni, cette fonction tentera de calculer automatiquement le temps de bit nominal du CAN (en remplaçant prescaler, bs1 et bs2) qui satisfait à la fois le baudrate (à 0,1 % près) et le sample_point souhaité (au pourcentage le plus proche). Pour un contrôle plus précis du timing du CAN, réglez directement les paramètres prescaler, bs1 et bs2.

  • sample_point spécifie la position de l’échantillon du bit par rapport à l’ensemble du temps de bit nominal, exprimée sous forme de pourcentage entier du temps de bit nominal. La valeur par défaut de sample_point est 75 %. Ce paramètre est ignoré sauf si baudrate est défini.

  • num_filter_banks pour le CAN classique, il s’agit du nombre de banques qui seront attribuées à CAN(1), les autres parmi les 28 étant attribuées à CAN(2).

Les paramètres restants ne sont présents que sur les cartes prenant en charge le CAN FD et configurent la fonctionnalité optionnelle CAN FD Bit Rate Switch (BRS) :

  • brs_prescaler est la valeur par laquelle l’horloge d’entrée du CAN FD est divisée pour générer les quanta de temps du bit de données. Le prédiviseur peut prendre une valeur comprise entre 1 et 32 inclus.

  • brs_sjw est la largeur de saut de resynchronisation en unités de quanta de temps pour les bits de données ; elle peut prendre une valeur comprise entre 1 et 16 inclus

  • brs_bs1 définit l’emplacement du point d’échantillonnage en unités de quanta de temps pour les bits de données ; il peut prendre une valeur comprise entre 1 et 32 inclus

  • brs_bs2 définit l’emplacement du point de transmission en unités de quanta de temps pour les bits de données ; il peut prendre une valeur comprise entre 1 et 16 inclus

  • brs_baudrate si un débit en bauds différent de 0 est fourni, cette fonction tentera de calculer automatiquement le temps de bit de données du CAN (en remplaçant brs_prescaler, brs_bs1 et brs_bs2) qui satisfait à la fois le brs_baudrate (à 0,1 % près) et le brs_sample_point souhaité (au pourcentage le plus proche). Pour un contrôle plus précis du timing BRS, réglez directement les paramètres brs_prescaler, brs_bs1 et brs_bs2.

  • brs_sample_point spécifie la position de l’échantillon du bit par rapport à l’ensemble du temps de bit nominal, exprimée sous forme de pourcentage entier du temps de bit nominal. La valeur par défaut de brs_sample_point est 75 %. Ce paramètre est ignoré sauf si brs_baudrate est défini.

Le quantum de temps tq est l’unité de base de temps pour le bus CAN. tq est la valeur du prédiviseur CAN divisée par PCLK1 (la fréquence du bus de périphériques interne 1) ; voir pyb.freq() pour déterminer PCLK1.

Un seul bit est composé du segment de synchronisation, qui vaut toujours 1 tq. Vient ensuite le segment de bit 1, puis le segment de bit 2. Le point d’échantillonnage se situe après la fin du segment de bit 1. Le point de transmission se situe après la fin du segment de bit 2. Le débit en bauds sera 1/bittime, où bittime vaut 1 + BS1 + BS2 multiplié par le quantum de temps tq.

Par exemple, sur l’OpenMV Cam H7 (PCLK1 = 100 MHz), un CAN à 250 kbps avec un point d’échantillonnage à 75 % peut être configuré avec prescaler=25, sjw=1, bs1=11, bs2=4 : tq = 25 / 100 MHz = 250 ns, bittime = (1 + 11 + 4) × 250 ns = 4 µs, point d’échantillonnage = (1 + 11) / 16 = 75%, et le débit en bauds est 1 / 4 µs = 250 kHz.

Consultez la section bxCAN / FDCAN du manuel de référence STM32 du microcontrôleur de l’OpenMV Cam pour plus de détails.

deinit() None

Désactive le bus CAN.

restart() None

Force un redémarrage logiciel du contrôleur CAN sans réinitialiser sa configuration.

Si le contrôleur entre dans l’état bus-off, il ne participera plus à l’activité du bus. Si le contrôleur n’est pas configuré pour redémarrer automatiquement (voir init()), cette méthode peut être utilisée pour déclencher un redémarrage, et le contrôleur suivra le protocole CAN pour quitter l’état bus-off et passer à l’état error active.

state() int

Renvoie l’état du contrôleur. La valeur de retour peut être l’une des suivantes :

  • CAN.STOPPED – le contrôleur est complètement éteint et réinitialisé ;

  • CAN.ERROR_ACTIVE – le contrôleur est activé et dans l’état Error Active (TEC et REC sont tous deux inférieurs à 96) ;

  • CAN.ERROR_WARNING – le contrôleur est activé et dans l’état Error Warning (TEC ou REC vaut au moins 96) ;

  • CAN.ERROR_PASSIVE – le contrôleur est activé et dans l’état Error Passive (TEC ou REC vaut au moins 128) ;

  • CAN.BUS_OFF – le contrôleur est activé mais ne participe pas à l’activité du bus (TEC a dépassé 255).

info(list: list | None = None) list

Obtient des informations sur les états d’erreur du contrôleur et sur ses tampons TX et RX. Si list est fourni, il doit s’agir d’un objet liste comportant au moins 8 entrées, qui seront remplies avec les informations. Sinon, une nouvelle liste sera créée et remplie. Dans les deux cas, la valeur de retour de la méthode est la liste renseignée.

Les valeurs de la liste sont :

  • valeur TEC

  • valeur REC

  • nombre de fois où le contrôleur est entré dans l’état Error Warning (revient à 0 après 65535)

  • nombre de fois où le contrôleur est entré dans l’état Error Passive (revient à 0 après 65535)

  • nombre de fois où le contrôleur est entré dans l’état Bus Off (revient à 0 après 65535)

  • nombre de messages TX en attente

  • nombre de messages RX en attente sur le fifo 0

  • nombre de messages RX en attente sur le fifo 1

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

Configure une banque de filtres :

  • bank est la banque de filtres du contrôleur CAN classique, ou l’index de filtre CAN FD, à configurer.

  • mode est le mode dans lequel le filtre doit fonctionner, voir les tableaux ci-dessous.

  • fifo indique dans quel fifo (0 ou 1) un message doit être stocké, s’il est accepté par ce filtre.

  • params est un tableau de valeurs qui définit le filtre. Le contenu du tableau dépend de l’argument mode.

Contenu du tableau params pour les contrôleurs CAN classique (OpenMV Cam M4 / M7) :

mode

Contenu de params

CAN.LIST16

Quatre identifiants 16 bits qui seront acceptés.

CAN.LIST32

Deux identifiants 32 bits qui seront acceptés.

CAN.MASK16

Deux paires id/masque 16 bits, par exemple (1, 3, 4, 4). La première paire (1, 3) accepte tous les identifiants ayant le bit 0 = 1 et le bit 1 = 0 ; la seconde paire (4, 4) accepte tous les identifiants ayant le bit 2 = 1.

CAN.MASK32

Une paire id/masque 32 bits (identique par ailleurs à CAN.MASK16).

Contenu du tableau params pour les contrôleurs CAN FD (OpenMV Cam H7 / H7 Plus / Pure Thermal) :

mode

Contenu de params

CAN.RANGE

Deux identifiants formant une plage d’identifiants acceptés.

CAN.DUAL

Deux identifiants qui seront acceptés (par exemple (1, 2)).

CAN.MASK

Une paire (id, mask) (par exemple (0x111, 0x7FF)).

  • rtr Pour les contrôleurs CAN classique, il s’agit d’un tableau de booléens qui indique si un filtre doit accepter un message de demande de transmission distante (remote transmission request). Si cet argument n’est pas fourni, il vaut False par défaut pour toutes les entrées. La longueur dépend de mode :

    mode

    len(rtr)

    Notes

    CAN.LIST16

    4

    CAN.LIST32

    2

    CAN.MASK16

    2

    CAN.MASK32

    1

    Pour le CAN FD, cet argument est ignoré.

  • extframe Si True, la trame aura un identifiant étendu (29 bits), sinon un identifiant standard (11 bits) est utilisé.

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

Efface et désactive une banque de filtres :

  • bank est la banque de filtres du contrôleur CAN classique, ou l’index de filtre CAN FD, à effacer.

  • extframe Pour les contrôleurs CAN FD, si True, efface un filtre étendu (configuré avec extframe=True), sinon efface un identifiant standard (configuré avec extframe=False).

any(fifo: int) bool

Renvoie True si un message est en attente sur le FIFO, sinon False.

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

Reçoit des données sur le bus :

  • fifo est un entier, qui est le FIFO sur lequel recevoir

  • list est un objet liste optionnel à utiliser comme valeur de retour

  • timeout est le délai d’attente en millisecondes pour la réception.

Valeur de retour : une liste contenant cinq valeurs.

  • L’id du message.

  • Un booléen qui indique si l’identifiant du message est standard ou étendu.

  • Un booléen qui indique si le message est un message RTR.

  • La valeur FMI (Filter Match Index).

  • Un tableau contenant les données.

Si list vaut None, une nouvelle liste sera allouée, ainsi qu’un nouvel objet bytes pour contenir les données (en tant que cinquième élément de la liste).

Si list n’est pas None, il doit s’agir d’un objet liste comportant au moins cinq éléments. Le cinquième élément doit être un objet memoryview créé soit à partir d’un bytearray, soit à partir d’un array de type “B” ou “b”, et ce tableau doit disposer d’assez de place pour au moins 8 octets. L’objet liste sera alors rempli avec les quatre premières valeurs de retour ci-dessus, et l’objet memoryview sera redimensionné sur place à la taille des données et rempli avec ces données. Les mêmes objets liste et memoryview peuvent être réutilisés lors d’appels ultérieurs à cette méthode, offrant ainsi un moyen de recevoir des données sans utiliser le tas. Par exemple

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

Envoie un message sur le bus :

  • data sont les données à envoyer (un entier à envoyer, ou un objet tampon).

  • id est l’id du message à envoyer.

  • timeout est le délai d’attente en millisecondes pour l’envoi.

  • rtr est un booléen qui indique si le message doit être envoyé en tant que demande de transmission distante (remote transmission request). Si rtr vaut True, seule la longueur de data est utilisée pour renseigner le champ DLC de la trame ; les octets réels de data ne sont pas utilisés.

  • extframe si True, la trame aura un identifiant étendu (29 bits), sinon un identifiant standard (11 bits) est utilisé.

  • fdf pour les contrôleurs CAN FD, s’il est réglé sur True, la trame aura un format de trame FD, qui prend en charge des charges utiles de données allant jusqu’à 64 octets.

  • brs pour les contrôleurs CAN FD, s’il est réglé sur True, le mode de commutation de débit est activé, dans lequel la phase de données est transmise à un débit différent. Voir CAN.init() pour les paramètres de configuration du timing du bit de données.

Si timeout vaut 0, le message est placé dans l’un des trois tampons matériels et la méthode retourne immédiatement. Si les trois tampons sont utilisés, une exception est levée. Si timeout est différent de 0, la méthode attend que le message soit transmis. Si le message ne peut pas être transmis dans le temps spécifié, une exception est levée.

Valeur de retour : None.

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

Enregistre une fonction à appeler lorsqu’un message est accepté dans un FIFO vide :

  • fifo est le FIFO de réception.

  • fun est la fonction à appeler lorsque le FIFO devient non vide.

La fonction de rappel prend deux arguments : le premier est l’objet CAN lui-même ; le second est un entier qui indique la raison de l’appel :

Raison

Signification

0

Un message a été accepté dans un FIFO vide.

1

Le FIFO est plein.

2

Un message a été perdu en raison d’un FIFO plein.

Exemple d’utilisation de 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)

Constantes

Constantes de mode de bus (argument mode de init()) :

NORMAL: int

Le contrôleur participe normalement au bus – il transmet ses propres trames et acquitte les trames valides reçues.

LOOPBACK: int

Mode bouclage interne : le contrôleur est déconnecté des broches et redirige les trames transmises directement vers le chemin de réception. Utile pour les autotests sans émetteur-récepteur.

SILENT: int

Mode écoute seule : le contrôleur reçoit les trames mais ne pilote jamais le bus (pas d’ACK, pas de transmissions). Utile pour l’écoute du bus.

SILENT_LOOPBACK: int

Combine SILENT et LOOPBACK : aucune activité sur les broches et aucun acquittement, avec bouclage interne du TX vers le RX.

Constantes d’état du contrôleur (renvoyées par state()) :

STOPPED: int

Le contrôleur est complètement éteint et réinitialisé.

ERROR_ACTIVE: int

Le contrôleur est activé et dans l’état Error Active (TEC et REC sont tous deux inférieurs à 96).

ERROR_WARNING: int

Le contrôleur est activé et dans l’état Error Warning (TEC ou REC vaut au moins 96).

ERROR_PASSIVE: int

Le contrôleur est activé et dans l’état Error Passive (TEC ou REC vaut au moins 128).

BUS_OFF: int

Le contrôleur est activé mais ne participe pas à l’activité du bus (TEC a dépassé 255).

Modes de filtre CAN classique (argument mode de setfilter() sur l’OpenMV Cam M4 / M7) :

LIST16: int

Le tableau params du filtre contient quatre identifiants 16 bits qui seront acceptés.

LIST32: int

Le tableau params du filtre contient deux identifiants 32 bits qui seront acceptés.

MASK16: int

Le tableau params du filtre contient deux paires (id, mask) 16 bits.

MASK32: int

Le tableau params du filtre contient une paire (id, mask) 32 bits.

Modes de filtre CAN FD (argument mode de setfilter() sur l’OpenMV Cam H7 / H7 Plus / Pure Thermal) :

RANGE: int

Le tableau params du filtre contient deux identifiants formant une plage d’identifiants acceptés.

DUAL: int

Le tableau params du filtre contient deux identifiants spécifiques à accepter.

MASK: int

Le tableau params du filtre contient une paire (id, mask).