Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


Before Posting...

Please check out the Community Guidelines in the Announcements and Administration Category.

PCIe to I2C Bridge Windows Driver

ganesh45inganesh45in Member Posts: 3
edited March 25 in NTDEV

Hi All,

We have a product here which is a PCIe to I2C/SPI bridge. We are required to write a Windows Driver to control the I2C controller present inside the PCIe chip.

The hardware connection looks like this:

| |
| HostPC | ------- > PCIe to I2C bridge Device connected to PCIe slot---> I2C slave device
||

I went through the Simple Peripheral Bus (SPB) framework for this I2C controller. But the documentation is mainly concentrated on the I2C controller that are part of the SOC platform. For example, the documentation says that the information about the SPB controller or SPB peripheral device should be present as a part of the ACPI table.

My device here is not statically connected to any system. This PCIe switch can be connected by the customer whenever he needs and he just does a reboot of the PC to get that enumerated by the OS. So we cannot define this as part of the ACPI table.

Also it says that the application cannot directly send data to and from the SPB controller driver. We need to have a SPB peripheral driver also that bridges the application and the SPB controller.

My use case is like this:

Provide the I2C controller driver for the PCIe to I2C bridge. I will provide specific IOCTLs to send Write or Read commands from the application. Let the customer connect whatever I2C device they want to be connected to the I2C controller. Let them drive that peripheral from the application without the need for a peripheral driver in between.

I like my device to be acting as a USB to I2C bridge. Something like this:
https://www.totalphase.com/products/aardvark-i2cspi/

Is there a Windows device driver framework to support my use case?
Or to better frame my question, How can I go about this?

P.S: I am pretty new to WIndows drivers. I have a fair knowledge on Linux drivers though.

Thanks,
Ganesh.

Post edited by ganesh45in on

Comments

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,399

    Welcome to the forum, and thanks for taking the time to write such a clear and complete description of what you are trying to accomplish.

    Because of your specific use case, you simply would write an ordinary PCI device driver that controls your I2C controller at the bottom edge, and that takes whatever Reads, Writes, and a Ioctls that you wish to define from your user app at the top edge.

    There’s no need for you to fit your driver (or your I2C controller) into the Windows SPB framework, because of your use case: Specifically, you do not want or need Windows PnP to enumerate the Client Device that’s attached to your I2C controller, find the “best” driver for it, and load that driver. Rather, you want Windows to match your driver to your PCIe Controller board, and then you’ll provide a generic interface (probably accessed via a nice user-mode DLL) that user apps use to access the various registers on the I2C client device that’s connected to your controller.

    So, that’s pretty easy! You get to ignore everything in Windows about I2C because Windows does not get involved in the management of your I2C bus or the device that’s connected to it.

    Sounds like a fun project! Good,luck,

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,907

    As Peter said, this is not a hard driver to write, but I have to wonder why you would do so. I2C and SPI are slow busses, thousands of times slower than PCIe. Why would you go to the expense of developing and certifying a PCIe board, when there are (as you mentioned) USB-to-SPI chips that already exist off the shelf?

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • rusakov2rusakov2 Member Posts: 24

    Tim,
    yes there are chips which do that. I have dealt recently with MCP2221A which is exactly that - USB-to-I2c.
    But....
    Microchip company does not provide a good native Windows 10 driver for MCP2221A, there is only legacy DLL with proprietary functions to read and write to i2c. I.e. when used in Windows 10 the MCP2221A chip when plugged in into USB will not appear as any particular class device. One has to call some function in DLL to find out if it was connected and if i2c controller is alive.
    So, in general using USB-to-i2c chips works in Windows 10 but cumbersome, and is subject to vendor support.
    I can see that someone may wish to have a well formed i2c controllers (perhaps many of those) on single PCIe card recognized by Windows 10 as proper class devices. Since if you don't then Windows 10 has no idea your system has i2c controller.

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,907

    when used in Windows 10 the MCP2221A chip when plugged in into USB will not appear as any particular class device.

    RIght, because there IS no pre-defined device class for I2C adapters. Any driver you write for this will be a custom device with a custom API. That's true for many devices. That shouldn't be an impediment for you.

    I can see that someone may wish to have a well formed i2c controllers (perhaps many of those) on single PCIe card recognized by Windows 10 as proper class devices. Since if you don't then Windows 10 has no idea your system has i2c controller.

    The point of having pre-defined device classes is so Windows can provide an abstraction API. There is no I2C device class, so there is no I2C abstraction API. This is not the fault of the vendors. There is not much call for I2C devices in the corporate world, which is where Windows is king. Look, I2C is slow and uncomplicated. You need Detect, Read, and Write. As long as the DLL provides that, what's the problem?

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,399

    There is no I2C device class, so there is no I2C abstraction API

    Except in the land of Windows IoT, where (a) I2C is much more likely to be used as Mr. Roberts alludes, and (b) there’s a very complete abstraction available in C# (at least).

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • ganesh45inganesh45in Member Posts: 3
    edited March 27

    Hi Peter,

    Thanks for the detailed and quick explanation. Really appreciate that :) I have few more doubts.

    Because of your specific use case, you simply would write an ordinary PCI device driver that controls your I2C controller at the bottom edge, and that takes whatever Reads, Writes, and a Ioctls that you wish to define from your user app at the top edge.

    There is another use case to the one I mentioned in my description. There could be a need wherein, instead of the application directly sending command to the controller to control the peripheral beneath, there could be a KMDF or UMDF peripheral driver present for that peripheral device in the OS. So in this case, the application will not directly talk to controller driver. but talks to the peripheral driver.
    This could be achieved using the SPB framework if we are static and using the ACPI table to define the devices and the connections. But unfortunately we are not.
    Is there anyway to use the SPB framework and escape from using the ACPI table for Controller and peripheral binding? From the documentation I could see that, there are too much dependencies on the ACPI table. For example, to get the target connection settings, the controller driver needs to call SpbTargetGetConnectionParameters. This API is inturn reading through the ACPI table to obtain the device's settings.

    I am thinking if I can somehow achieve the I2C/SPI controller to device binding without ACPI and through some other means, I can reuse the SPB framework and achieve both the use cases.

    IS there a way out here??

    Thanks,
    Ganesh

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,399

    There could be a need wherein, instead of the application directly sending command to the controller to control the peripheral beneath, there could be a KMDF or UMDF peripheral driver present for that peripheral device in the OS.

    Well, that's almost 100% different from your first use case... And it changes the design COMPLETELY. This is a MUCH harder ask.

    If your goal is to allow "standard" WDF drivers to be recognized and loaded for devices that are attached to your controller, I don't see any reasonable way of avoiding having the device described in the ACPI BIOS. The Client Driver is going to try to open a Remote I/O Target connection to the Controller Driver via the Resource Hub (ACPIEX). ACPIEX is going to try to determine which Controller the Client device is attached to by looking through the ACPI BIOS tables.

    If you wanted to be really fancy and complex, I suppose you could:

    • Write a bus driver that enumerates the device(s) connected to your controller. Because there's no standard way to dynamically enumerate the I2C bus, you'd have to create some method that users specify the device(s) connected to your I2C Controller's bus (as well as the Client IDs associated with each of those devices). You'll also need to be clever enough to "fake" a Connection ID for the Client driver to use when it enumerates its resources and attempt to open the connection to the Resource Hub.

    • Write a filter driver that intercepts Open requests that are sent to the Resource Hub, and redirect the open (via STATUS_REPARSE) to your Controller Driver.

    • Ensure your Controller Driver takes into account (that is, effectively "emulates") the behavior that the Client Driver would expect if it were talking to a Controller Driver via the SPBCx. So, you'll need to support the "standard" IOCTLs.

    I think you'll be able to avoid actual use of the SPB Controller Extensions entirely if you do the above. They don't really provide any advantage or help in your case... and I suspect that once the Client Driver gets his Connection ID and has opened a Remote I/O Target to your Controller Driver, it'll start sending you those standard IOCTLs.

    The above ignores the case where the Client device has some other resources other than the I2C Connection. For example, this doesn't allow you support for connections from the I2C device to a GPIO controller for interrupts (which is pretty common). I really don't see how you could support interrupts on the Client devices you enumerate... GPIO controller isn't under your control, after all.

    ANYhow... having to load the standard driver (and not just allow an app to do write and read) really turns this from a simple project into what is basically a research project. You're waaaay out of the standard ways of doing things.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Pavel_APavel_A Member Posts: 2,764

    I really don't see how you could support interrupts on the Client devices

    And here comes the PCIe interface. PCIe is very good with interrupts.
    PCI(e) is also more reliable than USB (TL;DR) so it can be preferred for unattended systems (servers, industrial...) even if cost is higher.

    --pa

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,399

    PCIe is very good with interrupts.

    From an I2C device that expects to be connected via a GPIO controller?

    So, now you’re telling me the OP has also neglected to tell us about the other 50% of his project in which his PCIe card has a GPIO controller on it, and he needs to write control that as well?

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Pavel_APavel_A Member Posts: 2,764

    I suspect that the OP still holds some interesting details up his sleeve...
    Same logic on the PCIe device that drives I2C can also receive interrupt requests. Not any "GPIO controller. As you and Mr. Roberts wrote previously it can be a simple PCI device, or a custom bus parent . It now depends on the class of the I2C devices - should they use in-box drivers or can be custom as well.

    Let my bits go on the wire!
    -- pa

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,399

    Not any "GPIO controller.”

    The OPs board supports “ordinary” I2C Client devices, which connect to an I2C bus and (perhaps, depending on the device) one or more interrupts. On the interrupt side, Client device expects to talk to a GPIO controller. It’s simple for you to write “ Same logic on the PCIe device that drives I2C can also receive interrupt requests” — but it’s not so simple in the hardware. You need to match logic levels and timing. You need to accommodate the potential for multiple interrupts in the same way you’d accommodate multiple GPIOs... if you’re going to pipe these to multiple MSIs there needs to be some logic involved, right?

    I really don’t think it’s as simple as you seem to think. You can’t just wire one or more lines that are designed to pull high or low (depending on the device) to generate an interrupt to your PCIe interface chip. You have an FPGA out there to do all this matching and mapping?

    Peter Viscarola
    OSR
    @OSRDrivers

  • rusakov2rusakov2 Member Posts: 24
    edited March 29

    @Peter_Viscarola_(OSR) said:

    There is no I2C device class, so there is no I2C abstraction API

    Except in the land of Windows IoT, where (a) I2C is much more likely to be used as Mr. Roberts alludes, and (b) there’s a very complete abstraction available in C# (at least).

    Peter

    Exactly right Peter ! In fact as I recall the entire spbclx is now a part of OneCore, not just for Windows IoT. Therefore a PCIe card with a proprietary ic2 host controller could be nicely supported by a proper driver into a well formed i2c class device on Windows 10. Moverover, shall one such exist I may even be interested to order it for future designs.

    Mr. Roberts, i2c is a bit slow, yes, but still very important, in some areas in fact is the key for the instrument, such as Tektronix analyzer. One of our systems has five(5) i2c host controllers, since there are many components to communicate with. Yes on Windows 10.

    Thanks,
    Sergey

  • rusakov2rusakov2 Member Posts: 24

    @Tim_Roberts said:

    Right, because there IS no pre-defined device class for I2C adapters. Any driver you write for this will be a custom device with a custom API.

    i2c host controller is not a custom device in Windows 10. i2c host controller is a supported type of device.
    SPB Framework Extension (SpbCx)
    For example Intel implemented i2c host controller connected to PCIe on Core-i5 based board.

    00:15.0 Signal processing controller: Intel Corporation Sunrise Point-LP Serial IO I2C Controller #0 (rev 21)
    Subsystem: Intel Corporation Device 7270
    Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
    Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- SERR- <PERR- INTx-
    Interrupt: pin A routed to IRQ 16
    .....

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 8,399

    Therefore a PCIe card with a proprietary ic2 host controller could be nicely supported by a proper driver into a well formed i2c class device on Windows 10

    Yes, well... that’s true. I2C controllers, in general, are backplane bus type devices (supported by PCI.SYS).

    However, the issue is that... regardless of how the Controller is interfaced, the Client devices still need to be listed in the ACPI BIOS, because the I2C bus is not dynamically enumerable.

    And, as I said earlier... it’s not typically a matter of JUST I2C. I2C (and SPI) connected devices are often designed to connect to one or more GPIOs to allow them to signal conditions.

    Anyhow... your project is turning into something that’s feeling far too complicated to reasonably design via forum posts.

    Good luck with your project. It’s an interesting one, for sure.

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • ganesh45inganesh45in Member Posts: 3

    Hi Peter and others,

    Thanks for spending time in helping me out here. Looks like I triggered a ruckus here ;). I am still a fair bit away from understanding the entire Windows driver architecture. I will go through the suggestions and comments from everyone here and try to progress. I will keep you guys updated in case I break through this.

    Thanks again for your time :)

    Ganesh.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Developing Minifilters 24 May 2021 Live, Online
Writing WDF Drivers 14 June 2021 Live, Online
Internals & Software Drivers 2 August 2021 Live, Online
Kernel Debugging 27 Sept 2021 Live, Online