Community
cancel
Showing results for 
Search instead for 
Did you mean: 
SCorb
Beginner
1,373 Views

Trouble using Apollo Lake GPIO in Windows

I've been following the https://docs.microsoft.com/en-us/windows-hardware/drivers/gpio/ Windows GPIO Driver Design Guide and have the Intel Controller Driver installed; which I downloaded from https://www.intel.com/content/dam/www/public/us/en/zip/atom-e3900-board-support-package-iot-platform... here.

I then followed the https://github.com/Microsoft/Windows-driver-samples/tree/master/gpio/samples/simdevice WDK GPIO simdevice sample making only changes to the inf to load for the new ACPI device I defined in a new BIOS build. My new ACPI device shows up in the Windows device manager, my simdevice peripheral driver loads for it and PrepareHardware hands me the 8 GpioIo I defined in ASL. When calling WdfCmResourceListGetDescriptor(ResourcesTranslated, index); for each resource their descriptor types are CmResourceTypeConnection; as expected. Their connection class is CM_RESOURCE_CONNECTION_CLASS_GPIO and their connection type is CM_RESOURCE_CONNECTION_TYPE_GPIO_IO. It seems like that part is working properly.

In order to send the IOCTL_GPIO_READ_PINS to the controller driver the sample indicates I need to:

  1. Create an IoTarget with the ParentObject set to the WDFDEVICE that my peripheral driver created. Shown https://github.com/Microsoft/Windows-driver-samples/blob/master/gpio/samples/simdevice/simdevice.c# L704 here.
  2. Open the IoTarget specifying a RequestString and the desired access levels
    1. The RequestString is created by using the RESOURCE_HUB_CREATE_PATH_FROM_ID macro. I provide the ConnectionId of the GPIO I want to target. The ConnectionId was provided to my driver during PrepareHardware.
  3. Create a WdfRequest and WdfMemory object with the data to pass to the IOCTL.
  4. Format the request for the IOCTL
  5. Send the IOCTL

However, step 2 above is failing with a STATUS_INVALID_PARAMETER. This step is done at https://github.com/Microsoft/Windows-driver-samples/blob/master/gpio/samples/simdevice/simdevice.c# L741 line 741 of the sample.

Any help in making the IOCTL_GPIO_READ_PINS and IOCTL_GPIO_WRITE_PINS calls to the controller driver would be greatly appreciated.

0 Kudos
3 Replies
Adolfo_S_Intel
Moderator
257 Views

Hello, scorbin,

Thanks for contacting us, we are investigating your case, and we will provide more information as soon as possible.

Best Regards,

Adolfo Sanchez.

SCorb
Beginner
257 Views

AdolfoS,

I've been doing some follow-up testing to make sure I've addressed the issue. It looks like the way I was requesting the ResourceString using the RESOURCE_HUB_CREATE_PATH_FROM_ID was incorrect. It expects me to provide a UNICODE_STRING for the framework to populate. I was doing this improperly. I found 2 WDK samples that illustrate how to do this.

1) This i2c example that shows how to get the ResourceString from the resource hub.

 

https://github.com/Microsoft/Windows-driver-samples/blob/master/usb/UcmTcpciCxClientSample/I2C.cpp# L192 Windows-driver-samples/I2C.cpp at master · Microsoft/Windows-driver-samples · GitHub

It does it like so:

// Create the device path using the connection ID.

DECLARE_UNICODE_STRING_SIZE(ResourceString, RESOURCE_HUB_PATH_SIZE);

RESOURCE_HUB_CREATE_PATH_FROM_ID(

&ResourceString,

DeviceContext->I2CConnectionId.LowPart,

DeviceContext->I2CConnectionId.HighPart);

2) This https://github.com/Microsoft/Windows-driver-samples/blob/master/gpio/samples/simdevice/simdevice.c# L741 GPIO example that shows how to get the ResourceString from the resource hub.

UNICODE_STRING ResourceString;

WCHAR ResourceStringBuffer[100];

RtlInitEmptyUnicodeString(

&ResourceString,

ResourceStringBuffer,

sizeof(ResourceStringBuffer));

RESOURCE_HUB_CREATE_PATH_FROM_ID(

&ResourceString,

SampleDrvExtension->ConnectionIds[0].LowPart,

SampleDrvExtension->ConnectionIds[0].HighPart);

I initially started with method 2. That wasn't working so I switched to method 1; because it seems more logical. It turns out I had an issue with my connectionID index first so it didn't matter which method I used. Once I corrected that method 1 wasn't working. Once I reverted to method 2 I was able to get past this issue.

Adolfo_S_Intel
Moderator
257 Views

Hello, scorbin

Thanks for sharing your solution with the rest of the community, your contribution is greatly appreciated.

Best Regards,

Adolfo Sanchez

Reply