Enabling APIC interrupt on GPIOs

razor1000razor1000 New Member Posts: 14

Hi guys,
I'm having some trouble with my HID-over-I2C device. Everything is functionally working, but there are huge spikes of latency between when the GPIO asserts and when the system starts to read the data from the HID-over-I2C device. With no changes in the BIOS, the spikes could be as long as 20ms, which is rather awful. I'm expecting a max latency of maybe 2ms.

I enabled the "GPIO low latency" option in the CRB, and it cut the response latency by about half. Now I only see worst-case spikes of about 10ms. But that's still too much.

I was thinking maybe the latency is being caused by the GPIO interrupt being shared with all the other GPIOs. I know it is possible to configure the pin to cause an APIC interrupt instead, which seems like it might be faster, since the channels are not shared. Unfortunately I don't know how to configure the pins to use the APIC interrupt.

**Is there a way to configure GPIOs on the HAT connector to use the APIC interrupt instead of the GPIO interrupt using a BIOS setting or changing an ACPI table ? **

I noticed that enabling the "Touch Pad" or "Touch Panel" in the CRB allows you to configure the interrupt as GPIO or APIC. I tried enabling the "Touch Pad" using the APIC interrupt, but there was a resource conflict error in device manager. The IRQ it used was 0x18, which I think is for pin A0, and I have no idea where that pin is routed. I didn't try APIC with the "Touch Panel" because I don't know where I2C1 is routed. This is the functionality that I need, but with a different pin.

I'm enabling the HID-over-I2C device by overloading the "ssdt4" table (the PINCTRL table) using Microsoft's ASL compiler. (I'm using Windows 10). The instructions are here:
https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/microsoft-asl-compiler

These are the I2C and GPIO settings I'm using. The pin is GPIO11 on the HAT connector.

        Method (_CRS, 0, Serialized)  // _CRS: Current Resource Settings
        {
            Name (SBFI, ResourceTemplate ()
            {
                I2cSerialBusV2 (0x0024, ControllerInitiated, 0x00061A80,
                    AddressingMode7Bit, "\\_SB.PCI0.I2C3",
                    0x00, ResourceConsumer,,,
                    )

                GpioInt(Level, ActiveLow, Shared, PullDefault, 0x0000, "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer,,)
                {
                    0x0076
                }
            })
            Return (SBFI) /* \_SB_.PCI0.I2C3.TPNL._CRS.SBFI */
        }

Comments

  • jaymanjayman New Member Posts: 64 ✭✭

    Based on the information here: https://docs.microsoft.com/en-us/windows/uwp/devices-sensors/enable-usermode-access

    In the GPIO section it states the following (among other requirements):

    Each pin requires both a GpioIO and a GpioInt resource. The GpioInt resource must immediately follow the GpioIO resource and must refer to the same pin number.
    The EdgeLevel field of the GpioInt descriptor must be Edge
    The ActiveLevel field of the GpioInt descriptor must be ActiveBoth
    The PinConfig field
    Must be the same in both the GpioIO and GpioInt descriptors
    Must be one of PullUp, PullDown, or PullNone. It cannot be PullDefault.

    It seems all of those rules are violated with the code snippet you posted.

    I have not tried using a GpioInt resource without an associated GpioIO resource, but using both the way outlined in that document (as well as following the other rules stated in that section) has worked fine for me to enable GPIO interrupts.

Sign In or Register to comment.