### AQPXLIB I2C controller setup and scan example Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-controller-method-compatibility?q= Shows how to create a PxI2CBus and PxI2CController, attach the controller to the bus, scan for devices, and detach. Requires an AqProtocolExerciser connection on port 60600. ```python from aqpxlib import AqProtocolExerciser from aqpxlib.i2c import PxI2CBus, PxI2CController with AqProtocolExerciser.connect(port=60600) as px: i2c_bus = PxI2CBus(px, scl=0, sda=1) i2c = PxI2CController(px) i2c.attach_to_bus(i2c_bus) addrs = i2c.scan() print(f"Found devices at: {[hex(a) for a in addrs]}") i2c.detach_from_bus() ``` -------------------------------- ### Quick start: attach PxI2CFifoTarget and enqueue TX data Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-fifo-target?q= Quick start example: connects to an AqProtocolExerciser on port 60600, creates an I2C bus on SCL=0/SDA=1, attaches a PxI2CFifoTarget at address 0x50, enqueues three bytes, prints TX fill and total read/written counters, then detaches from the bus. ```python from aqpxlib import AqProtocolExerciser from aqpxlib.i2c import PxI2CBus, PxI2CFifoTarget with AqProtocolExerciser.connect(port=60600) as px: i2c_bus = PxI2CBus(px, scl=0, sda=1) target = PxI2CFifoTarget(px, address=0x50) target.attach_to_bus(i2c_bus) target.enqueue([0x01, 0x02, 0x03]) state = target.state print(f"TX fill: {state.tx_fill}") print(f"Total read: {state.total_read}") print(f"Total written: {state.total_written}") target.detach_from_bus() ``` -------------------------------- ### Install aqpxlib with uv Source: https://acute-technology-inc.github.io/pxlib-docs/getting-started Installs aqpxlib using uv, the recommended package manager. ```bash uv add aqpxlib ``` -------------------------------- ### Event registration and handler setup for I3C (run_i3c_event_example.py) Source: https://acute-technology-inc.github.io/pxlib-docs/basic-tutorials/event-registration?q= Complete example that connects to the Protocol Exerciser, configures an I3C bus, attaches a controller and a 32-bit register target, subscribes to the 'i3_c_target_assigned_address' event using the @i3c_target.on_event decorator, and performs DAA to trigger the handler. The handler logs the assigned address and sets a threading.Event; the script asserts the event fires within 3 seconds. Requires a running Protocol Exerciser on port 60600. ```python import logging import threading from aqpxlib import AqProtocolExerciser from aqpxlib.i3c import ( ACUTE_DEFAULT_PID, PxI3CBus, PxI3CBaseController, PxI3C32BitRegisterTarget, ) from aqpxlib.event import PxEventMsg from aqpxlib.exceptions import PxAPIError logger = logging.getLogger(__name__) def exec_i3c_event_example(): """Basic event registration and handler setup example for I3C. Steps will be performed in the following order: 1. Create and open a connection to Acute's Protocol Exerciser. 2. Setting proper configuration of voltage levels and pull-up resistors on the bus. 3. Create an I3C Bus Handle Interface. 4. Attach an I3C controller and a target device to the bus. 5. Subscribe to the event of the target device. 6. Perform Dynamic Address Assignment procedure (This is where we receive the assigned address event from) """ with AqProtocolExerciser.connect(port=60600) as px_session: logger.info("Created an Exerciser session") # Configure an I3C Bus on SCL pin 0 and SDA pin 1 i3c_bus = PxI3CBus(px_session, scl=0, sda=1) logger.info(f"Created {i3c_bus}") # Setting the voltage level to 3.3V and pull-up resistance to 1.5kΩ i3c_bus.voltage = 3300 i3c_bus.pullup_resistance = 1500 # Create a Controller device i3c_controller = PxI3CBaseController(px_session, name="i3c_controller") try: i3c_controller.attach_to_bus(i3c_bus) except PxAPIError: logger.warning("Multiple controller is not supported right now, using the existing controller") i3c_controller = i3c_bus.get_current_controller() logger.info(f"Added a I3C controller with name {i3c_controller.name}") # Create a Target Device bcr = 0x00 # Bus Characteristic Register dcr = 0x00 # Device Characteristic Register pid = ACUTE_DEFAULT_PID | (0x01 << 32) | 0 # Provisioned ID i3c_target = PxI3C32BitRegisterTarget( px_session, name="i3c_target", static_addr=0x12, sub_address_type=PxI3C32BitRegisterTarget.SubAddressType.NONE, bcr=bcr, dcr=dcr, pid=pid, ) i3c_target.attach_to_bus(i3c_bus) logger.info(f"Added a I3C 32-bit register target with name {i3c_target.name}") # Subscribe to the assigned address event of the target device event = threading.Event() @i3c_target.on_event("i3_c_target_assigned_address") def i3c_target_assigned_address_handler(event_msg: PxEventMsg): """Handler for the assigned address event of the target device.""" assigned_address = event_msg.device_event.i3_c_target_assigned_address.assigned_address logger.info(f"I3C target assigned address: 0x{assigned_address:02x}") event.set() # Here we directly perform DAA, which will assign the dynamic address to the target device, # so our subscribed hander should be called. i3c_controller.do_daa() logger.info("Controller performed DAA") # to make sure we received our event assert event.wait(timeout=3), "Event has never been called" # Detach the devices from the bus i3c_target.detach_from_bus() i3c_controller.detach_from_bus() logger.info(f"Detached the controller and target from the bus") if __name__ == "__main__": logging.basicConfig(format='[%(levelname)s] %(message)s') logger.setLevel(logging.INFO) exec_i3c_event_example() ``` -------------------------------- ### Setup PxI2CController and scan for devices Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-controller-method-compatibility Shows the AQPXLIB setup: create a PxI2CBus with SCL/SDA pins, create a PxI2CController, attach it to the bus, then scan for devices. The controller must be attached before any transaction. Detach from the bus when done. ```python from aqpxlib import AqProtocolExerciser from aqpxlib.i2c import PxI2CBus, PxI2CController with AqProtocolExerciser.connect(port=60600) as px: i2c_bus = PxI2CBus(px, scl=0, sda=1) i2c = PxI2CController(px) i2c.attach_to_bus(i2c_bus) addrs = i2c.scan() print(f"Found devices at: {[hex(a) for a in addrs]}") i2c.detach_from_bus() ``` -------------------------------- ### Install aqpxlib into virtual environment Source: https://acute-technology-inc.github.io/pxlib-docs/getting-started Installs aqpxlib into the active virtual environment using uv. ```bash # install aqpxlib into the virtual environment uv add aqpxlib ``` -------------------------------- ### Install aqpxlib with pip Source: https://acute-technology-inc.github.io/pxlib-docs/getting-started Installs aqpxlib using pip as an alternative to uv. ```bash pip install aqpxlib ``` -------------------------------- ### Set up Context7 in Cursor with npx ctx7 setup --cursor Source: https://acute-technology-inc.github.io/pxlib-docs/context7-mcp Run this command in Cursor to authenticate with Context7, configure the MCP server in ~/.cursor/mcp.json, and install a skill that can invoke Context7 automatically. Restart Cursor after setup. ```bash npx ctx7 setup --cursor ``` -------------------------------- ### Quick start: attach target and read/write memory Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-8bit-address-memory-target?q= Quick start example: attaches a PxI2C8BitAddressMemoryTarget to an I2C bus, writes and reads memory directly from Python, then detaches. Uses port 60600 and address 0x50. ```python from aqpxlib import AqProtocolExerciser from aqpxlib.i2c import PxI2CBus, PxI2C8BitAddressMemoryTarget with AqProtocolExerciser.connect(port=60600) as px: i2c_bus = PxI2CBus(px, scl=0, sda=1) target = PxI2C8BitAddressMemoryTarget(px, address=0x50) target.attach_to_bus(i2c_bus) target.write_mem(0x10, [0x01, 0x02, 0x03, 0x04]) assert target.read_mem(0x10, 4) == [0x01, 0x02, 0x03, 0x04] target.detach_from_bus() ``` -------------------------------- ### Run the event registration example Source: https://acute-technology-inc.github.io/pxlib-docs/basic-tutorials/event-registration?q= Command to run the event registration example script from the terminal. ```bash $ python run_i3c_event_example.py ``` -------------------------------- ### Expected output for assigned address event example Source: https://acute-technology-inc.github.io/pxlib-docs/basic-tutorials/event-registration?q= Expected output from the decorator-style event subscription example. Shows the target device being assigned address 0x08 after DAA. ```text [INFO] Created an Exerciser session [INFO] Created I3C Bus (SCL: 0, SDA: 1) [INFO] Added a I3C controller with name i3c_controller [INFO] Added a I3C 32-bit register target with name i3c_target [INFO] Controller performed DAA [INFO] I3C target assigned address: 0x08 [INFO] Detached the controller and target from the bus ``` -------------------------------- ### Run command for run_i3c_example.py Source: https://acute-technology-inc.github.io/pxlib-docs/basic-tutorials/bus-device-creation?q= Command to execute the example script from the terminal. ```bash $ python run_i3c_example.py ``` -------------------------------- ### Attach and use PxI2C4KbMemoryTarget with write_mem/read_mem Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-4kb-memory-target?q= Quick start example: attach a PxI2C4KbMemoryTarget to an I2C bus and use write_mem/read_mem to preload and verify memory without going through the I2C controller. The target uses a static I2C address (0x50) and a 16-bit sub-address. ```python from aqpxlib import AqProtocolExerciser from aqpxlib.i2c import PxI2CBus, PxI2C4KbMemoryTarget with AqProtocolExerciser.connect(port=60600) as px: i2c_bus = PxI2CBus(px, scl=0, sda=1) target = PxI2C4KbMemoryTarget(px, address=0x50) target.attach_to_bus(i2c_bus) target.write_mem(0x0100, [0x01, 0x02, 0x03, 0x04]) assert target.read_mem(0x0100, 4) == [0x01, 0x02, 0x03, 0x04] target.detach_from_bus() ``` -------------------------------- ### `config` Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-8bit-address-memory-target Gets the configuration of the target. ```APIDOC ## `config` ### Description Gets the configuration of the target. ### Method Property ### Parameters None ### Response - **config** (object) - Configuration object. ``` -------------------------------- ### config Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/pwm/pwm-tx Gets the current configuration of the PWM Tx instance. ```APIDOC ## config ### Description Gets the current configuration of the PWM Tx instance. ### Method config ### Parameters None ### Response Returns the configuration object. ``` -------------------------------- ### MicroPython-compat NACK handling example Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-controller-method-compatibility Shows how MicroPython-compatible methods raise `OSError(errno.EIO, "I2C NACK")` when the target does not acknowledge the transaction. The example catches the exception and asserts the error number matches `errno.EIO`. ```python import errno try: i2c.readfrom(0x7F, 1) except OSError as e: assert e.errno == errno.EIO ``` -------------------------------- ### PxI2CFifoTarget usage example Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-fifo-target Shows how to create a PxI2CFifoTarget, attach it to an I2C bus, handle fifo_target_recv events, and perform read/write operations with a PxI2CController. The example asserts that read-back data matches enqueued bytes and that received data matches written bytes. ```python from aqpxlib import AqProtocolExerciser, PxEventMsg from aqpxlib.i2c import PxI2CBus, PxI2CController, PxI2CFifoTarget with AqProtocolExerciser.connect(port=6060) as px: i2c_bus = PxI2CBus(px, scl=0, sda=1) target = PxI2CFifoTarget(px, address=0x50) target.attach_to_bus(i2c_bus) controller = PxI2CController(px) controller.attach_to_bus(i2c_bus) received: list[int] = [] @target.on_event("fifo_target_recv") def on_recv(event: PxEventMsg) -> None: recv_event = event.device_event.fifo_target_recv received.extend(recv_event.data) target.enqueue([0xAA, 0xBB, 0xCC]) read_back = controller.i2c_read(target.address, 3) assert read_back == [0xAA, 0xBB, 0xCC] controller.i2c_write(target.address, [0x11, 0x22]) assert received == [0x11, 0x22] controller.detach_from_bus() target.detach_from_bus() ``` -------------------------------- ### Run command: python run_gpio_trigger_example.py Source: https://acute-technology-inc.github.io/pxlib-docs/basic-tutorials/gpio-trigger?q= Command to execute the example script. Run from the directory containing the script. ```bash python run_gpio_trigger_example.py ``` -------------------------------- ### name Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/pwm/pwm-tx Gets the name of the PWM Tx instance. ```APIDOC ## name ### Description Gets the name of the PWM Tx instance. ### Method name ### Parameters None ### Response Returns the name as a string. ``` -------------------------------- ### direct_getcaps Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i3c/i3c-base-controller?q= Direct GETCAPS command to get capabilities. ```APIDOC ## direct_getcaps ### Description Direct GETCAPS command to get capabilities. ### Parameters - **addresses** - Target addresses. - **defining_byte** - Defining byte for the command. - **count** - Number of addresses. - **header_policy** - Header policy for the command. - **stop_type** - Stop type for the command. ``` -------------------------------- ### config Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/uart/uart-rx?q= Gets the configuration of the UART Rx protocol. ```APIDOC ## config ### Description Gets the configuration of the UART Rx protocol. ### Method config ### Parameters None ### Response Returns the configuration. ``` -------------------------------- ### PxI2CController.writeto_then_readfrom() Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-controller-method-compatibility Performs a combined write-then-read operation with a repeated START condition. ```APIDOC ## writeto_then_readfrom() ### Description Performs a combined write-then-read operation with a repeated START condition. ### Method writeto_then_readfrom ### Parameters - **addr** (int) - Required - 7-bit device address. - **write_buf** (bytes-like) - Required - Data to write. - **read_nbytes** (int) - Required - Number of bytes to read. - **write_start** (int) - Optional - Start index in write buffer. - **write_end** (int) - Optional - End index in write buffer. - **stop** (bool) - Optional - Stop condition (default True). ### Returns - **bytes** - The data read. ### Example ```python data = i2c.writeto_then_readfrom(0x50, b'cmd', 4) ``` ``` -------------------------------- ### run_i3c_example.py - Full I3C bus and device creation example Source: https://acute-technology-inc.github.io/pxlib-docs/basic-tutorials/bus-device-creation?q= Complete example script that creates an I3C bus, attaches a controller and a 32-bit register target, initializes the bus, performs private write/read operations, and detaches devices. Requires a Protocol Exerciser connection on port 60600. The script logs each step and handles the case where a controller already exists. ```python import logging from aqpxlib import AqProtocolExerciser from aqpxlib.i3c import ( ACUTE_DEFAULT_PID, PxI3CBus, PxI3CBaseController, PxI3C32BitRegisterTarget, ) from aqpxlib.exceptions import PxAPIError logger = logging.getLogger(__name__) def exec_i3c_example(): """Basic demonstration of how to interact with Acute's Protocol Exerciser. Steps will be performed in the following order: 1. Create and open a connection to Acute's Protocol Exerciser. 2. Setting proper configuration of voltage levels and pull-up resistors on the bus. 3. Create an I3C Bus Handle Interface. 4. Attach an I3C controller and a target device to the bus. 5. Initialize the I3C bus to perform Dynamic Address Assignment procedure. 6. Perform Write / Read data to the target device. 7. Detach the devices and close the connection to the Protocol Exerciser. """ with AqProtocolExerciser.connect(port=60600) as px_session: logger.info("Created an Exerciser session") # Configure an I3C Bus on SCL pin 0 and SDA pin 1 i3c_bus = PxI3CBus(px_session, scl=0, sda=1) logger.info(f"Created {i3c_bus}") # Setting the voltage level to 3.3V and pull-up resistance to 1.5kΩ i3c_bus.voltage = 3300 i3c_bus.pullup_resistance = 1500 # Create a Controller device i3c_controller = PxI3CBaseController(px_session, name="i3c_controller") try: i3c_controller.attach_to_bus(i3c_bus) except PxAPIError: logger.warning("Multiple controller is not supported, using the existing controller") i3c_controller = i3c_bus.get_current_controller() logger.info(f"Added a I3C controller with name {i3c_controller.name}") # Create a Target Device bcr = 0x00 # Bus Characteristic Register dcr = 0x00 # Device Characteristic Register pid = ACUTE_DEFAULT_PID | (0x01 << 32) | 0 # Provisioned ID i3c_target = PxI3C32BitRegisterTarget( px_session, name="i3c_target", static_addr=0x12, sub_address_type=PxI3C32BitRegisterTarget.SubAddressType.NONE, bcr=bcr, dcr=dcr, pid=pid, ) i3c_target.attach_to_bus(i3c_bus) logger.info(f"Added a I3C 32-bit register target with name {i3c_target.name}") # Initialize the I3C bus, which follows the procedure defined in the I3C specification i3c_controller.init_bus() logger.info("I3C bus initialized") # Fetch the target's state to get the target's assigned dynamic address assigned_address = i3c_target.assigned_address logger.info(f"Target assigned dynamic address: {assigned_address}") # Perform Write / Read data to the target device is_ack = i3c_controller.private_write(assigned_address, [0xDE, 0xAD, 0xBE, 0xEF]) logger.info(f"I3C target" + (" acknowledged the write" if is_ack else " did not acknowledge the write")) data = i3c_controller.private_read(assigned_address, 4) logger.info(f"I3C target read data: {[f'{byte:02x}' for byte in data]}") # Detach the devices from the bus i3c_target.detach_from_bus() i3c_controller.detach_from_bus() logger.info(f"Detached the controller and target from the bus") if __name__ == "__main__": logging.basicConfig(format='[%(levelname)s] %(message)s') logger.setLevel(logging.INFO) exec_i3c_example() ``` -------------------------------- ### Connect and import GPIO helpers Source: https://acute-technology-inc.github.io/pxlib-docs/basic-tutorials/gpio?q= Sets up an AqProtocolExerciser connection to localhost:60600 and imports PxIoState from aqpxlib.gpio for GPIO operations. Use as a template for all GPIO scripts on this page. ```python from aqpxlib import AqProtocolExerciser from aqpxlib.gpio import PxIoState with AqProtocolExerciser.connect(host="localhost", port=60600) as px: ... ``` -------------------------------- ### Create a session with AqProtocolExerciser.connect Source: https://acute-technology-inc.github.io/pxlib-docs/basic-tutorials/bus-device-creation?q= Shows how to open a session to the Protocol Exerciser using a with statement to ensure automatic closure. ```python with AqProtocolExerciser.connect(port=60600) as px_session: # session `px_session` is opened # do something here ... ``` -------------------------------- ### `name` Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-8bit-address-memory-target Gets the name of the target. ```APIDOC ## `name` ### Description Gets the name of the target. ### Method Property ### Parameters None ### Response - **name** (string) - Name of the target. ``` -------------------------------- ### Quick start: attach target and enqueue TX data Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-fifo-target Shows how to connect to an AqProtocolExerciser, create an I2C bus and target, attach the target, enqueue data, print state, and detach. ```python from aqpxlib import AqProtocolExerciser from aqpxlib.i2c import PxI2CBus, PxI2CFifoTarget with AqProtocolExerciser.connect(port=60600) as px: i2c_bus = PxI2CBus(px, scl=0, sda=1) target = PxI2CFifoTarget(px, address=0x50) target.attach_to_bus(i2c_bus) target.enqueue([0x01, 0x02, 0x03]) state = target.state print(f"TX fill: {state.tx_fill}") print(f"Total read: {state.total_read}") print(f"Total written: {state.total_written}") target.detach_from_bus() ``` -------------------------------- ### `address` Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-8bit-address-memory-target Gets the I2C address of the target. ```APIDOC ## `address` ### Description Gets the I2C address of the target. ### Method Property ### Parameters None ### Response - **address** (integer) - I2C address. ``` -------------------------------- ### Create a virtual environment with uv Source: https://acute-technology-inc.github.io/pxlib-docs/getting-started Creates a virtual environment using uv. ```bash # create a virtual environment uv venv ``` -------------------------------- ### `cts_op_name` Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-8bit-address-memory-target Gets the CTS operation name. ```APIDOC ## `cts_op_name` ### Description Gets the CTS operation name. ### Method Property ### Parameters None ### Response - **cts_op_name** (string) - CTS operation name. ``` -------------------------------- ### Buffer slicing: start/end parameters Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-controller-method-compatibility Shows how AQPXLIB extends writeto, readfrom_into, and writeto_then_readfrom with optional start/end slice parameters for reusing large buffers. ```python buf = bytearray(8) i2c.writeto(0x42, buf, start=2, end=6) # write buf[2:6] i2c.readfrom_into(0x42, buf, start=1, end=5) # read into buf[1:5] ``` -------------------------------- ### `state` Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-8bit-address-memory-target Gets the current state of the target. ```APIDOC ## `state` ### Description Gets the current state of the target. ### Method Property ### Parameters None ### Response - **state** (string) - Current state of the target. ``` -------------------------------- ### Expected output of run_i3c_example.py Source: https://acute-technology-inc.github.io/pxlib-docs/basic-tutorials/bus-device-creation?q= Expected log output when running the example script, showing the sequence of operations and the assigned dynamic address. ```text [INFO] Created an Exerciser session [INFO] Created I3C Bus (SCL: 0, SDA: 1) [INFO] Added a I3C controller with name i3c_controller [INFO] Added a I3C 32-bit register target with name i3c_target [INFO] I3C bus initialized [INFO] Target assigned dynamic address: 0x08 [INFO] I3C target acknowledged the write [INFO] I3C target read data: ['0xde', '0xad', '0xbe', '0xef'] [INFO] Detached the controller and target from the bus ``` -------------------------------- ### Connect to Exerciser with specific IP using AqProtocolExerciser.connect Source: https://acute-technology-inc.github.io/pxlib-docs/basic-tutorials/set-a-specific-ip Use AqProtocolExerciser.connect with a specific host and port to control the Exerciser. The first example uses localhost, the second uses a specific IP address (192.168.1.1). Both use port 60600. ```python with AqProtocolExerciser.connect(host="localhost", port=60600) as exerciser_session: # code of some controlling flow ``` ```python with AqProtocolExerciser.connect(host="192.168.1.1", port=60600) as exerciser_session: # code of some controlling flow ``` -------------------------------- ### config Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/uart/uart-tx?q= Gets the configuration of the UART Tx protocol. ```APIDOC ## config ### Description Gets the configuration of the UART Tx protocol. ### Method config ### Parameters None ### Response Returns the configuration. ``` -------------------------------- ### name Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/uart/uart-tx?q= Gets the name of the UART Tx protocol. ```APIDOC ## name ### Description Gets the name of the UART Tx protocol. ### Method name ### Parameters None ### Response Returns the protocol name. ``` -------------------------------- ### run_gpio_trigger_example.py: Arm GPIO width trigger and handle event Source: https://acute-technology-inc.github.io/pxlib-docs/basic-tutorials/gpio-trigger?q= Complete script that connects to the Protocol Exerciser, registers a handler for the gpio_trigger event, arms a width-in-range trigger on pin 8, and sends a pulse to trigger it. Requires a running exerciser on port 60600. The handler logs the pin, duration, and polarity, and sets an event to signal completion. ```python import logging import threading from aqpxlib import AqProtocolExerciser from aqpxlib.event import PxEventMsg from aqpxlib.gpio import PxGpioWidthTriggerMode, PxIoState logger = logging.getLogger(__name__) def run_gpio_trigger_example() -> None: with AqProtocolExerciser.connect(port=60600) as px: done = threading.Event() def on_gpio_trigger(event_msg: PxEventMsg) -> None: g = event_msg.global_event.gpio_trigger logger.info( "GPIO trigger: pin=%d duration_ns=%d polarity=%s", g.pin_idx, g.pulse_duration, g.pulse_polarity, ) done.set() px.add_event_handler("gpio_trigger", on_gpio_trigger) pin = 8 px.set_gpio_trigger( gpio_idx=pin, min_duration_ns=500, max_duration_ns=50_000, low_pulse=True, high_pulse=True, mode=PxGpioWidthTriggerMode.TRIGGER_PULSE_WIDTH_IN_RANGE, ) px.send_gpio_pulse( gpio_idx=pin, active_state=PxIoState.HIGH, idle_state=PxIoState.LOW, active_time_ns=5000, ) assert done.wait(timeout=3), "GPIO trigger event not received" if __name__ == "__main__": logging.basicConfig(format="[%(levelname)s] %(message)s") logger.setLevel(logging.INFO) run_gpio_trigger_example() ``` -------------------------------- ### name Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/uart/uart-rx?q= Gets the name of the UART Rx protocol. ```APIDOC ## name ### Description Gets the name of the UART Rx protocol. ### Method name ### Parameters None ### Response Returns the protocol name. ``` -------------------------------- ### Configure an I3C Bus on SCL pin 0 and SDA pin 1 Source: https://acute-technology-inc.github.io/pxlib-docs/basic-tutorials/bus-device-creation?q= Creates an I3C bus handle on the Protocol Exerciser using the PxI3CBus constructor with scl=0 and sda=1. The constructor automatically sends a request to configure the bus. Constructing a bus with the same protocol and channel configuration reuses the existing handle index and does not send a topology update. ```python # Configure an I3C Bus on SCL pin 0 and SDA pin 1 i3c_bus = PxI3CBus(px_session, scl=0, sda=1) ``` -------------------------------- ### Manual MCP configuration with API key Source: https://acute-technology-inc.github.io/pxlib-docs/context7-mcp Manual MCP configuration for Cursor using an API key. Add this to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project). Create an API key in the Context7 dashboard and replace YOUR_CONTEXT7_API_KEY. Do not commit API keys to git. ```json { "mcpServers": { "context7": { "url": "https://mcp.context7.com/mcp", "headers": { "Context7-API-Key": "YOUR_CONTEXT7_API_KEY" } } } } ``` -------------------------------- ### `get_event_handlers` Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-8bit-address-memory-target Gets the event handlers for a specified event. ```APIDOC ## `get_event_handlers` ### Description Gets the event handlers for a specified event. ### Method Method ### Parameters - **event** (string) - Required - Event name. ### Response - **handlers** (array) - List of event handler functions. ``` -------------------------------- ### `additional_data` Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-8bit-address-memory-target Gets additional data associated with the target. ```APIDOC ## `additional_data` ### Description Gets additional data associated with the target. ### Method Property ### Parameters None ### Response - **additional_data** (object) - Additional data. ``` -------------------------------- ### Typical usage of PxI3CBaseController Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i3c/i3c-base-controller?q= Shows the typical lifecycle: create a bus, create a controller, attach to the bus, perform operations, then detach. The ellipsis represents any controller-initiated operation. ```python i3c_bus = PxI3CBus(exerciser_session) i3c_controller = PxI3CBaseController(exerciser_session) i3c_controller.attach_to_bus(i3c_bus) ... # Do any operation initiated from this controller i3c_controller.detach_from_bus() ``` -------------------------------- ### direct_getstatus Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i3c/i3c-base-controller?q= Direct GETSTATUS command to get device status. ```APIDOC ## direct_getstatus ### Description Direct GETSTATUS command to get device status. ### Parameters - **addresses** - Target addresses. - **defining_byte** - Defining byte for the command. - **count** - Number of addresses. - **header_policy** - Header policy for the command. - **stop_type** - Stop type for the command. ``` -------------------------------- ### PxI3CBaseController Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i3c/i3c-base-controller?q= Constructor for the PxI3CBaseController class. Initializes a new I3C basic controller device class. ```APIDOC ## PxI3CBaseController ### Description Constructor for the PxI3CBaseController class. Initializes a new I3C basic controller device class. ### Method Constructor ### Signature ```python PxI3CBaseController( exerciser: AqProtocolExerciser, *args, config: I3CControllerConfig | None = None, **kwargs ) ``` ### Parameters - **exerciser** (AqProtocolExerciser) - Required - The protocol exerciser session. - **config** (I3CControllerConfig | None) - Optional - Configuration for the I3C controller. ### Usage Example ```python i3c_bus = PxI3CBus(exerciser_session) i3c_controller = PxI3CBaseController(exerciser_session) i3c_controller.attach_to_bus(i3c_bus) ... # Do any operation initiated from this controller i3c_controller.detach_from_bus() ``` ``` -------------------------------- ### direct_getpid Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i3c/i3c-base-controller?q= Direct GETPID command to get product ID. ```APIDOC ## direct_getpid ### Description Direct GETPID command to get product ID. ### Parameters - **addresses** - Target addresses. - **header_policy** - Header policy for the command. ``` -------------------------------- ### Activate virtual environment on different platforms Source: https://acute-technology-inc.github.io/pxlib-docs/getting-started Activates the virtual environment on Bash, Windows CMD, and Windows PowerShell. ```bash $ source .venv/bin/activate ``` ```cmd > .venv\Scripts\activate.bat ``` ```powershell PS> .venv\Scripts\Activate.ps1 ``` -------------------------------- ### Set and Get IBI event with PxI3C Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i3c/FAQ/set-get-ibi Connects to an AqProtocolExerciser, sets up an I3C bus with a controller and a 32-bit register target, and registers an event handler for 'i3_c_controller_recv_ibi_data'. The target sends an IBI request with MDB and additional data, and the handler prints the event after a 1-second wait. ```python import time from aqpxlib import AqProtocolExerciser from aqpxlib.i3c import ( ACUTE_DEFAULT_PID, PxI3CBus, PxI3CBaseController, PxI3C32BitRegisterTarget, ) from aqpxlib.exceptions import PxAPIError with AqProtocolExerciser.connect(host="localhost", port=60600) as exerciser_session: exerciser_session.set_handles([]) # reset all handles i3c_bus = PxI3CBus(exerciser_session, scl=0, sda=1) i3c_controller = PxI3CBaseController(exerciser_session) i3c_controller.attach_to_bus(i3c_bus) i3c_target = PxI3C32BitRegisterTarget(exerciser_session, static_addr=0x12, bcr=0x06) i3c_target.attach_to_bus(i3c_bus) i3c_controller.init_bus() def event_handler(event): print(event) i3c_controller.add_event_handler("i3_c_controller_recv_ibi_data", event_handler) # target send IBI i3c_target.ibi_request( mdb_value=b"\xAA", additional_data=b"\x10\x30\x50" ) time.sleep(1) # Wait for the IBI request to be received and printed ``` -------------------------------- ### state Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/uart/uart-tx?q= Gets the current state of the UART Tx protocol. ```APIDOC ## state ### Description Gets the current state of the UART Tx protocol. ### Method state ### Parameters None ### Response Returns the current state. ``` -------------------------------- ### Find or Pick a Bus Source: https://acute-technology-inc.github.io/pxlib-docs/basic-tutorials/bus-device-creation Shows how to retrieve existing buses from the session and pick a specific I3C bus by its SCL and SDA pins. If no matching bus is found, a new one is created. ```python buses = px_session.get_buses() for bus in buses: print(bus) # e.g. "I3C Bus (SCL: 0, SDA: 1)" ``` ```python from aqpxlib.i3c import PxI3CBus def find_i3c_bus(buses, scl: int, sda: int) -> PxI3CBus | None: for bus in buses: if isinstance(bus, PxI3CBus) and bus.scl == scl and bus.sda == sda: return bus return None i3c_bus = find_i3c_bus(px_session.get_buses(), scl=0, sda=1) if i3c_bus is None: i3c_bus = PxI3CBus(px_session, scl=0, sda=1) ``` -------------------------------- ### state Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/uart/uart-rx?q= Gets the current state of the UART Rx protocol. ```APIDOC ## state ### Description Gets the current state of the UART Rx protocol. ### Method state ### Parameters None ### Response Returns the current state. ``` -------------------------------- ### Manual MCP configuration with OAuth Source: https://acute-technology-inc.github.io/pxlib-docs/context7-mcp Manual MCP configuration for Cursor using OAuth. Add this to ~/.cursor/mcp.json (global) or .cursor/mcp.json (project). After saving, restart Cursor and complete the OAuth sign-in when prompted. ```json { "mcpServers": { "context7": { "url": "https://mcp.context7.com/mcp/oauth" } } } ``` -------------------------------- ### state Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/pwm/pwm-tx Gets the current state of the PWM Tx instance. ```APIDOC ## state ### Description Gets the current state of the PWM Tx instance. ### Method state ### Parameters None ### Response Returns the current state. ``` -------------------------------- ### Typical usage of PxI2CController Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i2c/i2c-controller Typical usage example for the PxI2CController class. It creates a bus and controller, attaches the controller to the bus, performs operations, and then detaches from the bus. ```python i2c_bus = PxI2CBus(exerciser_session) i2c_controller = PxI2CController(exerciser_session) i2c_controller.attach_to_bus(i2c_bus) ... # Do any operation from this controller i2c_controller.detach_from_bus() ``` -------------------------------- ### Set and Get IBI Event with aqpxlib Source: https://acute-technology-inc.github.io/pxlib-docs/protocols/i3c/FAQ/set-get-ibi?q= Sets up an I3C bus on a connected AqProtocolExerciser, configures a controller and a target, and registers a custom event handler for the 'i3_c_controller_recv_ibi_data' event. After the target sends an IBI request, the handler prints the event; the script sleeps for one second to allow the event to be received. ```python import time from aqpxlib import AqProtocolExerciser from aqpxlib.i3c import ( ACUTE_DEFAULT_PID, PxI3CBus, PxI3CBaseController, PxI3C32BitRegisterTarget, ) from aqpxlib.exceptions import PxAPIError with AqProtocolExerciser.connect(host="localhost", port=60600) as exerciser_session: exerciser_session.set_handles([]) # reset all handles i3c_bus = PxI3CBus(exerciser_session, scl=0, sda=1) i3c_controller = PxI3CBaseController(exerciser_session) i3c_controller.attach_to_bus(i3c_bus) i3c_target = PxI3C32BitRegisterTarget(exerciser_session, static_addr=0x12, bcr=0x06) i3c_target.attach_to_bus(i3c_bus) i3c_controller.init_bus() def event_handler(event): print(event) i3c_controller.add_event_handler("i3_c_controller_recv_ibi_data", event_handler) # target send IBI i3c_target.ibi_request( mdb_value=b"\xAA", additional_data=b"\x10\x30\x50" ) time.sleep(1) # Wait for the IBI request to be received and printed ```