class I2CTarget —— 一个 I2C 目标设备¶
I2C 目标(target)是一种连接到 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()
请注意,某些移植版本要求向 I2CTarget 构造函数传入 id,以及可能还有 scl 和 sda 引脚,以选择其所连接的硬件 I2C 实例和引脚。
当配置为内存设备时,还可以注册以接收事件。例如,在内存被读取/写入时收到通知:
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 的引脚对象。
请注意,某些移植版本/开发板会为 scl 和 sda 提供默认值,可在此构造函数中更改。另一些则会为 scl 和 sda 提供固定值,无法更改。
通用方法¶
- irq(handler: Callable[[I2CTarget], None] | None = None, trigger: int = IRQ_END_READ | IRQ_END_WRITE, hard: bool = False) None¶
安装一个 IRQ
handler,当trigger所选事件之一触发时调用它。trigger是若干IRQ_*常量按位或(OR)组合而成的位掩码;默认在每次控制器侧读或写结束时触发。hard=True会注册一个硬中断处理程序(回调中不进行堆分配)。默认为调度回调。传入handler=None可禁用该中断。备注
IRQ_ADDR_MATCH_READ、IRQ_ADDR_MATCH_WRITE、IRQ_READ_REQ和IRQ_WRITE_REQ必须由硬 IRQ 回调(hard=True)处理,因为这些事件必须与硬件同步地予以确认。IRQ_END_READ和IRQ_END_WRITE既可由软回调也可由硬回调处理;所有事件共用单个处理程序,因此只要有任一事件需要硬回调,则全部都需要。当向构造函数提供内存缓冲区时,驱动会抑制仅用于写入内存地址的那次事务的
IRQ_END_WRITE。即使软 IRQ 调度器延迟了回调,这也能让事务结束事件保持有意义。
- memaddr¶
I2C 控制器最近所选内存地址的整数值(仅在构造函数中指定了
mem时有效)。
常量¶
每个
IRQ_*常量都是一个标志位。将它们按位或(OR)组合可构建用于irq()的trigger掩码。在处理程序内部,可通过将self.irq().flags()与各常量按位与(AND)来恢复已触发的事件集合。- IRQ_WRITE_REQ: int¶
当控制器已向目标时钟输入一个字节时触发。处理程序必须在控制器发送下一个字节之前调用
readinto()来取回该字节。仅限硬 IRQ。