คลาส 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()

โปรดทราบว่าบางพอร์ตกำหนดให้ส่ง id และอาจรวมถึงพิน scl และ sda ไปยังตัวสร้าง I2CTarget เพื่อเลือกอินสแตนซ์ 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 ที่ไม่สามารถเปลี่ยนแปลงได้

เมธอดทั่วไป

deinit() None

ยกเลิกการกำหนดค่าเป้าหมาย I2C หลังจากเรียกเมธอดนี้ ฮาร์ดแวร์จะไม่ตอบสนองต่อคำขอบนบัส I2C อีกต่อไป และไม่สามารถเรียกเมธอดอื่นได้

readinto(buf: bytearray) int

อ่านลงในบัฟเฟอร์ที่ระบุซึ่งมีไบต์ที่รอดำเนินการที่เขียนโดยคอนโทรลเลอร์ I2C คืนค่าจำนวนไบต์ที่อ่าน

write(buf: bytes) int

เขียนออกไบต์จากบัฟเฟอร์ที่ระบุ เพื่อส่งไปยังคอนโทรลเลอร์ I2C หลังจากที่คอนโทรลเลอร์ส่งคำขออ่าน คืนค่าจำนวนไบต์ที่เขียน บางพอร์ตยอมรับเพียงหนึ่งไบต์ต่อครั้งสำหรับเมธอดนี้

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

ติดตั้ง handler IRQ ที่ถูกเรียกเมื่อเหตุการณ์ใดเหตุการณ์หนึ่งที่เลือกโดย trigger ทำงาน trigger คือบิตมาสก์ของค่าคงที่ IRQ_* ที่ OR เข้าด้วยกัน โดยค่าเริ่มต้นจะทำงานเมื่อสิ้นสุดการอ่านหรือเขียนในฝั่งคอนโทรลเลอร์ทุกครั้ง

hard=True ลงทะเบียน hard-interrupt handler (ไม่มีการจัดสรร heap ในคอลแบ็ก) ค่าเริ่มต้นคือ scheduled callback ส่ง handler=None เพื่อปิดใช้งานอินเทอร์รัปต์

Note

IRQ_ADDR_MATCH_READ, IRQ_ADDR_MATCH_WRITE, IRQ_READ_REQ และ IRQ_WRITE_REQ ต้องได้รับการจัดการโดย hard IRQ callback (hard=True) เนื่องจากเหตุการณ์ต้องได้รับการยืนยันพร้อมกันกับฮาร์ดแวร์ IRQ_END_READ และ IRQ_END_WRITE สามารถจัดการได้โดย soft หรือ hard callbacks เหตุการณ์ทั้งหมดใช้ handler เดียวกัน ดังนั้นหากเหตุการณ์ใดต้องการ hard callback ทั้งหมดก็ต้องใช้เช่นกัน

เมื่อบัฟเฟอร์หน่วยความจำถูกส่งไปยังตัวสร้าง ไดรเวอร์จะระงับ IRQ_END_WRITE สำหรับธุรกรรมที่เพิ่งเขียนที่อยู่หน่วยความจำ ซึ่งทำให้เหตุการณ์สิ้นสุดธุรกรรมยังคงมีความหมาย แม้ว่าตัวกำหนดเวลา soft-IRQ จะเลื่อนคอลแบ็ก

memaddr

ค่าจำนวนเต็มของที่อยู่หน่วยความจำล่าสุดที่ถูกเลือกโดยคอนโทรลเลอร์ I2C (ถูกต้องเฉพาะเมื่อระบุ mem ในตัวสร้าง)

ค่าคงที่

แต่ละค่าคงที่ IRQ_* คือบิตธง นำมา OR รวมกันเพื่อสร้างมาสก์ trigger สำหรับ irq() ภายใน handler ชุดของเหตุการณ์ที่ทำงานสามารถดึงได้ผ่าน self.irq().flags() AND กับแต่ละค่าคงที่

IRQ_ADDR_MATCH_READ: int

ทำงานเมื่อคอนโทรลเลอร์กำหนดที่อยู่เป้าหมายนี้สำหรับธุรกรรมการอ่าน (ไบต์ที่อยู่ได้รับพร้อมบิต read/write ตั้งค่าเป็น 1) เฉพาะ Hard-IRQ เท่านั้น

IRQ_ADDR_MATCH_WRITE: int

ทำงานเมื่อคอนโทรลเลอร์กำหนดที่อยู่เป้าหมายนี้สำหรับธุรกรรมการเขียน (ไบต์ที่อยู่ได้รับพร้อมบิต read/write ตั้งค่าเป็น 0) เฉพาะ Hard-IRQ เท่านั้น

IRQ_READ_REQ: int

ทำงานเมื่อคอนโทรลเลอร์ร้องขอไบต์จากเป้าหมาย handler ต้องเรียก write() เพื่อส่งไบต์ก่อนที่รอบสัญญาณนาฬิกาของคอนโทรลเลอร์จะเสร็จสิ้น เฉพาะ Hard-IRQ เท่านั้น

IRQ_WRITE_REQ: int

ทำงานเมื่อคอนโทรลเลอร์ส่ง clock-in ไบต์ไปยังเป้าหมาย handler ต้องเรียก readinto() เพื่อดึงไบต์ก่อนที่คอนโทรลเลอร์จะส่งไบต์ถัดไป เฉพาะ Hard-IRQ เท่านั้น

IRQ_END_READ: int

ทำงานเมื่อคอนโทรลเลอร์เสร็จสิ้นธุรกรรมการอ่าน (ได้รับ STOP / repeated START) สามารถจัดการได้โดย hard หรือ soft IRQ callback

IRQ_END_WRITE: int

ทำงานเมื่อคอนโทรลเลอร์เสร็จสิ้นธุรกรรมการเขียน (ได้รับ STOP / repeated START) สามารถจัดการได้โดย hard หรือ soft IRQ callback ถูกระงับสำหรับธุรกรรมที่เขียนที่อยู่หน่วยความจำเมื่อบัฟเฟอร์ mem ถูกส่งไปยังตัวสร้าง