class I2CTarget -- I2C ターゲットデバイス

I2C ターゲットは I2C バスに接続され、I2C コントローラによって制御されるデバイスです。I2C ターゲットはさまざまな形態をとることができます。machine.I2CTarget クラスは、メモリ/レジスタデバイスとして設定したり、(ポートがサポートしている場合は)コールバックを使用して任意の I2C デバイスとして設定したりできる I2C ターゲットを実装します。

OpenMV Cam M4 / M7 / H7 / H7 Plus / Pure Thermal / RT1062 / AE3 で利用可能です。

メモリデバイスの場合の使用例:

from machine import I2CTarget

# Create the backing memory for the I2C target.
mem = bytearray(8)

# Create an I2C target.  Depending on the port, extra parameters
# may be required to select the peripheral and/or pins to use.
i2c = I2CTarget(addr=67, mem=mem)

# At this point an I2C controller can read and write `mem`.
...

# Deinitialise the I2C target.
i2c.deinit()

一部のポートでは、接続先のハードウェア I2C インスタンスとピンを選択するために、id および場合によっては sclsda ピンを I2CTarget コンストラクタに渡す必要があることに注意してください。

メモリデバイスとして設定されている場合、イベントを受け取るために登録することもできます。例えば、メモリの読み書きが行われたときに通知を受けるには:

from machine import I2CTarget

# Define an IRQ handler, for I2C events.
def irq_handler(i2c_target):
    flags = i2c_target.irq().flags()
    if flags & I2CTarget.IRQ_END_READ:
        print("controller read target at addr", i2c_target.memaddr)
    if flags & I2CTarget.IRQ_END_WRITE:
        print("controller wrote target at addr", i2c_target.memaddr)

# Create the I2C target and register to receive default events.
mem = bytearray(8)
i2c = I2CTarget(addr=67, mem=mem)
i2c.irq(irq_handler)

より複雑な I2C デバイスは、すべてのイベントを使用して実装できます。例えば、イベントがトリガーされる際の生のイベントを確認するには:

from machine import I2CTarget

# Define an IRQ handler that prints the event id and responds to reads/writes.
def irq_handler(i2c_target, buf=bytearray(1)):
    flags = i2c_target.irq().flags()
    print(flags)
    if flags & I2CTarget.IRQ_READ_REQ:
        i2c_target.write(buf)
    if flags & I2CTarget.IRQ_WRITE_REQ:
        i2c_target.readinto(buf)

# Create the I2C target and register to receive all events.
i2c = I2CTarget(addr=67)
all_triggers = (
    I2CTarget.IRQ_ADDR_MATCH_READ
    | I2CTarget.IRQ_ADDR_MATCH_WRITE
    | I2CTarget.IRQ_READ_REQ
    | I2CTarget.IRQ_WRITE_REQ
    | I2CTarget.IRQ_END_READ
    | I2CTarget.IRQ_END_WRITE
)
i2c.irq(irq_handler, trigger=all_triggers, hard=True)

コンストラクタ

class machine.I2CTarget(id: int, addr: int, *, addrsize: int = 7, mem: bytearray | None = None, mem_addrsize: int = 8, scl: Pin | None = None, sda: Pin | None = None)

以下のパラメータを使用して新しい I2CTarget オブジェクトを構築して返します:

  • id は特定の I2C ペリフェラルを識別します。指定できる値はポートやボードによって異なります。一部のポートにはデフォルトがあり、その場合このパラメータは省略できます。

  • addr はターゲットの I2C アドレスです。

  • addrsize は I2C ターゲットアドレスのビット数です。有効な値は 7 と 10 です。

  • mem は書き込み可能なバッファプロトコルを持つオブジェクトです。指定されない場合、バッキングメモリは存在せず、データは I2CTarget.readinto() および I2CTarget.write() メソッドを使用して読み書きする必要があります。

  • mem_addrsize はメモリアドレスのビット数です。有効な値は 0、8、16、24、32 です。

  • scl は SCL に使用するピンを指定するピンオブジェクトです。

  • sda は SDA に使用するピンを指定するピンオブジェクトです。

一部のポートやボードでは sclsda にデフォルト値があり、このコンストラクタで変更できます。その他のポートでは sclsda が固定値で変更できない場合があります。

一般的なメソッド

deinit() None

I2C ターゲットの初期化を解除します。このメソッドが呼び出された後、ハードウェアは I2C バス上の要求に応答しなくなり、他のメソッドを呼び出すこともできなくなります。

readinto(buf: bytearray) int

I2C コントローラによって書き込まれた保留中のバイトを、指定されたバッファに読み込みます。読み込んだバイト数を返します。

write(buf: bytes) int

I2C コントローラが読み込み要求を送信した後に渡すために、指定されたバッファのバイトを書き出します。書き込んだバイト数を返します。ほとんどのポートはこのメソッドに対して一度に1バイトしか受け付けません。

irq(handler: Callable[[I2CTarget], None] | None = None, trigger: int = IRQ_END_READ | IRQ_END_WRITE, hard: bool = False) None

trigger で選択されたイベントのいずれかが発生したときに呼び出される IRQ handler をインストールします。triggerIRQ_* 定数を OR 結合したビットマスクです。デフォルトでは、コントローラ側のすべての読み書きの終了時に発生します。

hard=True はハード割り込みハンドラ(コールバック内でヒープ割り当てを行わない)を登録します。デフォルトはスケジュールされたコールバックです。割り込みを無効にするには handler=None を渡します。

注釈

IRQ_ADDR_MATCH_READIRQ_ADDR_MATCH_WRITEIRQ_READ_REQIRQ_WRITE_REQ は、イベントをハードウェアと同期して確認応答する必要があるため、ハード IRQ コールバック(hard=True)で処理する必要があります。IRQ_END_READIRQ_END_WRITE はソフトまたはハードのいずれのコールバックでも処理できます。すべてのイベントは単一のハンドラを共有するため、いずれかのイベントにハードコールバックが必要な場合はすべてに必要になります。

コンストラクタにメモリバッファが指定されている場合、ドライバはメモリアドレスを書き込むだけのトランザクションについては IRQ_END_WRITE を抑制します。これにより、ソフト IRQ スケジューラがコールバックを遅延させる場合でも、トランザクション終了イベントの意味が保たれます。

memaddr

I2C コントローラによって選択された最新のメモリアドレスの整数値です(コンストラクタで mem が指定されている場合のみ有効です)。

定数

IRQ_* 定数はフラグビットです。これらを OR 結合して irq() 用の trigger マスクを構築します。ハンドラ内では、発生したイベントの集合を self.irq().flags() を各定数と AND することで取得できます。

IRQ_ADDR_MATCH_READ: int

コントローラが読み込みトランザクションのためにこのターゲットをアドレス指定したときに発生します(読み書きビットが 1 に設定された状態でアドレスバイトが受信されたとき)。ハード IRQ 専用です。

IRQ_ADDR_MATCH_WRITE: int

コントローラが書き込みトランザクションのためにこのターゲットをアドレス指定したときに発生します(読み書きビットが 0 に設定された状態でアドレスバイトが受信されたとき)。ハード IRQ 専用です。

IRQ_READ_REQ: int

コントローラがターゲットからバイトを要求しているときに発生します。ハンドラは、コントローラのクロックサイクルが完了する前に write() を呼び出してバイトを供給する必要があります。ハード IRQ 専用です。

IRQ_WRITE_REQ: int

コントローラがターゲットにバイトをクロックインしたときに発生します。ハンドラは、コントローラが次のバイトを送信する前に readinto() を呼び出してバイトを取得する必要があります。ハード IRQ 専用です。

IRQ_END_READ: int

コントローラが読み込みトランザクションを終了したときに発生します(STOP / リピーテッドスタートを受信したとき)。ハードまたはソフトのいずれの IRQ コールバックでも処理できます。

IRQ_END_WRITE: int

コントローラが書き込みトランザクションを終了したときに発生します(STOP / リピーテッドスタートを受信したとき)。ハードまたはソフトのいずれの IRQ コールバックでも処理できます。コンストラクタに mem バッファが指定されている場合、メモリアドレスを書き込むトランザクションについては抑制されます。