class CAN -- コントローラエリアネットワーク通信バス

CAN はクラシック CAN(bxCAN、OpenMV Cam M4 および M7 で使用)と CAN FD(FDCAN、OpenMV Cam H7、H7 Plus、Pure Thermal で使用)の両方のコントローラをサポートします。物理レベルでは、CAN バスは RX と TX の 2 本の線で構成されます。OpenMV Cam を CAN バスに接続するには、CAN トランシーバを使用して MCU からの CAN 論理信号をバス上の適切な電圧レベルに変換する必要があります。

ループバック(トランシーバなし)モードのクラシック CAN:

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(FD フレーム、ビットレート切り替え、拡張フレーム ID、500 kbit/s のアービトレーションフェーズ、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)

以下の CAN モジュール関数とその引数は、特に明記されていない限り、クラシックおよび FD CAN コントローラの両方で利用できます。

コンストラクタ

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

指定した bus(整数のペリフェラルインデックス。例えば CAN1 なら 1CAN2 なら 2)上に CAN オブジェクトを構築します。追加のパラメータを指定しない場合、オブジェクトは作成されますが初期化されません(以前のバス設定があればそれを保持します)。追加の引数が指定された場合はバスが初期化されます。利用可能なパラメータについては CAN.init() を参照してください。

CAN(2) は、pyb.CAN を公開しているすべての OpenMV Cam(M4 / M7 / H7 / H7 Plus / Pure Thermal)で同じヘッダピンに配線されています。

信号

ヘッダピン

備考

RX

P3

TX

P2

CAN ペリフェラルは論理レベルの信号のみを提供します。実際の CAN バスを駆動するには外部の CAN トランシーバが必要です。

pyb.CAN は OpenMV Cam N6 では利用できません。

メソッド

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

指定したパラメータで CAN バスを初期化します:

  • mode は次のいずれかです: NORMAL、LOOPBACK、SILENT、SILENT_LOOPBACK

  • prescaler は、公称ビットタイムクォンタを生成するために CAN 入力クロックを分周する値です。プリスケーラは、クラシック CAN では 1 から 1024 まで、CAN FD では 1 から 512 まで(いずれも両端を含む)の値を取れます。

  • sjw は、公称ビットの時間クォンタ単位での再同期ジャンプ幅です。クラシック CAN では 1 から 4 まで、CAN FD では 1 から 128 まで(いずれも両端を含む)の値を取れます。

  • bs1 は、公称ビットの時間クォンタ単位でサンプルポイントの位置を定義します。クラシック CAN では 1 から 16 まで、CAN FD では 2 から 256 まで(いずれも両端を含む)の値を取れます。

  • bs2 は、公称ビットの時間クォンタ単位で送信ポイントの位置を定義します。クラシック CAN では 1 から 8 まで、CAN FD では 2 から 128 まで(いずれも両端を含む)の値を取れます。

  • auto_restart は、コントローラがバスオフ状態に入った後、自動的に通信の再開を試みるかどうかを設定します。これが無効の場合、restart() を使用してバスオフ状態から抜け出すことができます

  • baudrate に 0 以外のボーレートを指定すると、この関数は baudrate(誤差 .1% 以内)と希望する sample_point(最も近い 1% 単位)の両方を満たす CAN の公称ビットタイムを自動的に計算しようとします(prescalerbs1bs2 を上書きします)。CAN タイミングをより精密に制御するには、prescalerbs1bs2 パラメータを直接設定してください。

  • sample_point は、公称ビットタイム全体に対するビットサンプルの位置を、公称ビットタイムに対する整数のパーセンテージで指定します。sample_point のデフォルトは 75% です。このパラメータは baudrate が設定されていない限り無視されます。

  • num_filter_banks は、クラシック CAN において CAN(1) に割り当てられるバンクの数です。残りの 28 個のうちの残余は CAN(2) に割り当てられます。

残りのパラメータは、CAN FD をサポートするボードにのみ存在し、オプションの CAN FD ビットレート切り替え(BRS)機能を構成します:

  • brs_prescaler は、データビットタイムクォンタを生成するために CAN FD 入力クロックを分周する値です。プリスケーラは 1 から 32 まで(両端を含む)の値を取れます。

  • brs_sjw は、データビットの時間クォンタ単位での再同期ジャンプ幅です。1 から 16 まで(両端を含む)の値を取れます

  • brs_bs1 は、データビットの時間クォンタ単位でサンプルポイントの位置を定義します。1 から 32 まで(両端を含む)の値を取れます

  • brs_bs2 は、データビットの時間クォンタ単位で送信ポイントの位置を定義します。1 から 16 まで(両端を含む)の値を取れます

  • brs_baudrate に 0 以外のボーレートを指定すると、この関数は brs_baudrate(誤差 .1% 以内)と希望する brs_sample_point(最も近い 1% 単位)の両方を満たす CAN データビットタイムを自動的に計算しようとします(brs_prescalerbrs_bs1brs_bs2 を上書きします)。BRS タイミングをより精密に制御するには、brs_prescalerbrs_bs1brs_bs2 パラメータを直接設定してください。

  • brs_sample_point は、公称ビットタイム全体に対するビットサンプルの位置を、公称ビットタイムに対する整数のパーセンテージで指定します。brs_sample_point のデフォルトは 75% です。このパラメータは brs_baudrate が設定されていない限り無視されます。

時間クォンタ tq は CAN バスの基本的な時間単位です。tq は CAN プリスケーラ値を PCLK1(内部ペリフェラルバス 1 の周波数)で割ったものです。PCLK1 を確認するには pyb.freq() を参照してください。

1 つのビットは、同期セグメント(常に 1 tq)で構成されます。続いてビットセグメント 1、その後ビットセグメント 2 が続きます。サンプルポイントはビットセグメント 1 が終了した後です。送信ポイントはビットセグメント 2 が終了した後です。ボーレートは 1/bittime となり、bittime は 1 + BS1 + BS2 に時間クォンタ tq を乗じたものです。

例えば、OpenMV Cam H7(PCLK1 = 100 MHz)では、サンプルポイント 75% の 250 kbps CAN は prescaler=25, sjw=1, bs1=11, bs2=4 として構成できます: tq = 25 / 100 MHz = 250 nsbittime = (1 + 11 + 4) × 250 ns = 4 µs、サンプルポイント = (1 + 11) / 16 = 75%、ボーレートは 1 / 4 µs = 250 kHz となります。

詳細については、OpenMV Cam の MCU 用の STM32 リファレンスマニュアルの bxCAN / FDCAN セクションを参照してください。

deinit() None

CAN バスをオフにします。

restart() None

設定をリセットせずに CAN コントローラのソフトウェア再起動を強制します。

コントローラがバスオフ状態に入ると、バス活動に参加しなくなります。コントローラが自動再起動するよう設定されていない場合(init() を参照)、このメソッドを使用して再起動をトリガーできます。コントローラは CAN プロトコルに従ってバスオフ状態から抜け出し、エラーアクティブ状態に入ります。

state() int

コントローラの状態を返します。戻り値は次のいずれかです:

  • CAN.STOPPED -- コントローラは完全にオフでリセットされています。

  • CAN.ERROR_ACTIVE -- コントローラはオンでエラーアクティブ状態です(TEC と REC の両方が 96 未満)。

  • CAN.ERROR_WARNING -- コントローラはオンでエラーワーニング状態です(TEC または REC の少なくとも一方が 96 以上)。

  • CAN.ERROR_PASSIVE -- コントローラはオンでエラーパッシブ状態です(TEC または REC の少なくとも一方が 128 以上)。

  • CAN.BUS_OFF -- コントローラはオンですがバス活動に参加していません(TEC が 255 を超えてオーバーフローした)。

info(list: list | None = None) list

コントローラのエラー状態と TX および RX バッファに関する情報を取得します。list が指定された場合、それは少なくとも 8 個のエントリを持つリストオブジェクトであるべきで、その情報で埋められます。指定されない場合は新しいリストが作成されて埋められます。どちらの場合も、メソッドの戻り値は内容が埋められたリストです。

リスト内の値は次のとおりです:

  • TEC 値

  • REC 値

  • コントローラがエラーワーニング状態に入った回数(65535 を超えると 0 に巻き戻る)

  • コントローラがエラーパッシブ状態に入った回数(65535 を超えると 0 に巻き戻る)

  • コントローラがバスオフ状態に入った回数(65535 を超えると 0 に巻き戻る)

  • 保留中の TX メッセージ数

  • fifo 0 上の保留中の RX メッセージ数

  • fifo 1 上の保留中の RX メッセージ数

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

フィルタバンクを構成します:

  • bank は、構成するクラシック CAN コントローラのフィルタバンク、または CAN FD フィルタインデックスです。

  • mode はフィルタが動作するモードです。下記の表を参照してください。

  • fifo は、このフィルタによってメッセージが受け入れられた場合に、メッセージを格納する fifo(0 または 1)です。

  • params はフィルタを定義する値の配列です。配列の内容は mode 引数に依存します。

クラシック CAN コントローラ(OpenMV Cam M4 / M7)における params 配列の内容:

mode

params の内容

CAN.LIST16

受け入れられる 4 つの 16 ビット ID。

CAN.LIST32

受け入れられる 2 つの 32 ビット ID。

CAN.MASK16

2 組の 16 ビット ID/マスクペア。例えば (1, 3, 4, 4)。最初のペア(1, 3)はビット 0 = 1 かつビット 1 = 0 のすべての ID を受け入れます。2 番目のペア(4, 4)はビット 2 = 1 のすべての ID を受け入れます。

CAN.MASK32

1 組の 32 ビット ID/マスクペア(それ以外は CAN.MASK16 と同じ)。

CAN FD コントローラ(OpenMV Cam H7 / H7 Plus / Pure Thermal)における params 配列の内容:

mode

params の内容

CAN.RANGE

受け入れられる ID の範囲を形成する 2 つの ID。

CAN.DUAL

受け入れられる 2 つの ID(例: (1, 2))。

CAN.MASK

1 組の (id, mask) ペア(例: (0x111, 0x7FF))。

  • rtr クラシック CAN コントローラの場合、これはフィルタがリモート送信要求メッセージを受け入れるべきかどうかを示すブール値の配列です。この引数が指定されない場合、すべてのエントリは False がデフォルトになります。長さは mode に依存します:

    mode

    len(rtr)

    備考

    CAN.LIST16

    4

    CAN.LIST32

    2

    CAN.MASK16

    2

    CAN.MASK32

    1

    CAN FD の場合、この引数は無視されます。

  • extframe True の場合、フレームは拡張識別子(29 ビット)を持ちます。そうでない場合は標準識別子(11 ビット)が使用されます。

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

フィルタバンクをクリアして無効にします:

  • bank は、クリアするクラシック CAN コントローラのフィルタバンク、または CAN FD フィルタインデックスです。

  • extframe CAN FD コントローラの場合、True なら拡張フィルタ(extframe=True で構成されたもの)をクリアし、そうでなければ標準識別子(extframe=False で構成されたもの)をクリアします。

any(fifo: int) bool

FIFO 上で待機中のメッセージがあれば True を、なければ False を返します。

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

バス上でデータを受信します:

  • fifo は受信する FIFO を表す整数です

  • list は戻り値として使用されるオプションのリストオブジェクトです

  • timeout は受信を待機するミリ秒単位のタイムアウトです。

戻り値: 5 つの値を含むリスト。

  • メッセージの id。

  • メッセージ ID が標準か拡張かを示すブール値。

  • メッセージが RTR メッセージかどうかを示すブール値。

  • FMI(フィルタマッチインデックス)値。

  • データを含む配列。

listNone の場合、新しいリストが割り当てられ、データを含む新しい bytes オブジェクト(リストの 5 番目の要素として)も割り当てられます。

listNone でない場合、それは少なくとも 5 つの要素を持つリストオブジェクトであるべきです。5 番目の要素は、bytearray または型 'B' もしくは 'b' の配列から作成された memoryview オブジェクトであるべきで、この配列は少なくとも 8 バイトを収められる十分な空きがなければなりません。リストオブジェクトには上記の最初の 4 つの戻り値が埋め込まれ、memoryview オブジェクトはデータのサイズにインプレースでリサイズされてそのデータで埋められます。同じリストおよび memoryview オブジェクトはこのメソッドの後続の呼び出しで再利用でき、ヒープを使わずにデータを受信する方法を提供します。例えば:

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

バス上でメッセージを送信します:

  • data は送信するデータ(送信する整数、またはバッファオブジェクト)です。

  • id は送信するメッセージの id です。

  • timeout は送信を待機するミリ秒単位のタイムアウトです。

  • rtr は、メッセージをリモート送信要求として送信すべきかどうかを指定するブール値です。rtr が True の場合、data の長さのみがフレームの DLC スロットを埋めるために使用されます。data 内の実際のバイトは使用されません。

  • extframe True の場合、フレームは拡張識別子(29 ビット)を持ちます。そうでない場合は標準識別子(11 ビット)が使用されます。

  • fdf CAN FD コントローラの場合、True に設定すると、フレームは最大 64 バイトのデータペイロードをサポートする FD フレーム形式を持ちます。

  • brs CAN FD コントローラの場合、True に設定するとビットレート切り替えモードが有効になり、データフェーズが異なるビットレートで送信されます。データビットタイミングの構成パラメータについては CAN.init() を参照してください。

timeout が 0 の場合、メッセージは 3 つのハードウェアバッファのいずれかのバッファに置かれ、メソッドはただちに戻ります。3 つのバッファすべてが使用中の場合は例外がスローされます。timeout が 0 でない場合、メソッドはメッセージが送信されるまで待機します。指定された時間内にメッセージを送信できない場合は例外がスローされます。

戻り値: None

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

空の FIFO にメッセージが受け入れられたときに呼び出される関数を登録します:

  • fifo は受信側の FIFO です。

  • fun は FIFO が空でなくなったときに呼び出される関数です。

コールバック関数は 2 つの引数を取ります。1 つ目は CAN オブジェクト自体です。2 つ目はコールバックの理由を示す整数です:

理由

意味

0

空の FIFO にメッセージが受け入れられました。

1

FIFO が満杯です。

2

FIFO が満杯のためメッセージが失われました。

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)

定数

バスモード定数(init()mode 引数):

NORMAL: int

コントローラは通常どおりバスに参加します。自身のフレームを送信し、有効な受信フレームを確認応答します。

LOOPBACK: int

内部ループバックモード: コントローラはピンから切り離され、送信フレームを受信パスに直接ルーティングします。トランシーバなしのセルフテストに便利です。

SILENT: int

リッスンオンリーモード: コントローラはフレームを受信しますが、バスを駆動しません(ACK なし、送信なし)。バスのスニッフィングに便利です。

SILENT_LOOPBACK: int

SILENTLOOPBACK を組み合わせます: ピン活動も確認応答もなく、TX を RX に内部ループバックします。

コントローラ状態定数(state() が返す):

STOPPED: int

コントローラは完全にオフでリセットされています。

ERROR_ACTIVE: int

コントローラはオンでエラーアクティブ状態です(TEC と REC の両方が 96 未満)。

ERROR_WARNING: int

コントローラはオンでエラーワーニング状態です(TEC または REC の少なくとも一方が 96 以上)。

ERROR_PASSIVE: int

コントローラはオンでエラーパッシブ状態です(TEC または REC の少なくとも一方が 128 以上)。

BUS_OFF: int

コントローラはオンですがバス活動に参加していません(TEC が 255 を超えてオーバーフローした)。

クラシック CAN フィルタモード(OpenMV Cam M4 / M7 における setfilter()mode 引数):

LIST16: int

フィルタの params 配列は、受け入れられる 4 つの 16 ビット ID を保持します。

LIST32: int

フィルタの params 配列は、受け入れられる 2 つの 32 ビット ID を保持します。

MASK16: int

フィルタの params 配列は、2 組の 16 ビット (id, mask) ペアを保持します。

MASK32: int

フィルタの params 配列は、1 組の 32 ビット (id, mask) ペアを保持します。

CAN FD フィルタモード(OpenMV Cam H7 / H7 Plus / Pure Thermal における setfilter()mode 引数):

RANGE: int

フィルタの params 配列は、受け入れられる ID の範囲を形成する 2 つの ID を保持します。

DUAL: int

フィルタの params 配列は、受け入れる 2 つの特定の ID を保持します。

MASK: int

フィルタの params 配列は、1 組の (id, mask) ペアを保持します。