本文介绍了如何使用Win API函数与Intel Atom E3800系列的I2C驱动程序通信?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在试图找出如何使用Win API与I2C驱动程序通信几天之后,我希望你能帮助我。

after trying to figure out how to communicate with the I2C driver using the Win API for several days, I hope you can help me.

问题是使用驱动程序包中包含的I2Cpublic.h头文件中定义的全局唯一标识符I2C_LPSS_INTERFACE_GUID,找不到任何设备。应该在软件开发人员手册中按
在用户模式Win API函数中使用。

The problem is that no devices can be found using the global unique identifier I2C_LPSS_INTERFACE_GUID defined in the I2Cpublic.h header file which was included in the driver package and that should be used within the user-mode Win API functions according to the Software Developer's Manual.

要获取设备名称并为该设备创建句柄,我使用了以下过程:

To get the device name and create a handle for that device I used the following procedure:

1。获取与该GUID对应的设备接口类:

1. Get the device interface class corresponding to that GUID:

     hDvcInfoSet = SetupDiGetClassDevs(& I2C_LPSS_INTERFACE_GUID,NULL,NULL,DIGCF_ALLCLASSES)

     hDvcInfoSet = SetupDiGetClassDevs(&I2C_LPSS_INTERFACE_GUID, NULL, NULL, DIGCF_ALLCLASSES)

 

2。遍历所有设备信息元素,为每个元素创建一个接口并获取每个接口的详细信息:

2. Loop through all the devices information elements, create an interface for each element and get details about each interface:

     while(SetupDiEnumDeviceInfo(hDvcInfoSet,i,& devInfo)){

     while (SetupDiEnumDeviceInfo(hDvcInfoSet, i, &devInfo)) {

          if(devInfo.ClassGuid == I2C_LPSS_INTERFACE_GUID){

          if (devInfo.ClassGuid == I2C_LPSS_INTERFACE_GUID) {

               SetupDiCreateDeviceInterface(hDvcInfoSet,&安培; DEVINFO,&安培; I2C_LPSS_INTERFACE_GUID,NULL,0,&安培; dvcInterfaceData)

               SetupDiCreateDeviceInterface(hDvcInfoSet, &devInfo, &I2C_LPSS_INTERFACE_GUID, NULL, 0, &dvcInterfaceData)

         &NBSP ;     SetupDiGetDeviceInterfaceDetail(hDvcInfoSet,&安培; dvcInterfaceData,requiredSize,NULL,NULL)

               SetupDiGetDeviceInterfaceDetail(hDvcInfoSet, &dvcInterfaceData, requiredSize, NULL, NULL)

            &NBSP ;  i ++;

               i++;

          }

          }

     }

     }

3。在界面的详细信息中,可以找到可用于创建句柄的设备路径:

3. In the details of an interface the device path can be found which can be used to create a handle:

     hI2Ccontroller =的CreateFile(dvcInterfaceDetailData.DevicePath,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);

     hI2Ccontroller = CreateFile(dvcInterfaceDetailData.DevicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

的问题是,即没有带有GUID的设备信息元素,所以我查看了用于安装I2C控制器驱动程序的设置信息文件(iaioi2c.inf)。



有还定义了一个ClassGuid,但它与头文件中的那个不对应。



因此我尝试了另一个GUID然后我找到了几个设备信息元素使用这个标识符并为每个标识符创建一个接口以获取设备路径。



那些路径,其中root,acpi或pci的任何一部分已经让我困惑,因为我以为我仅对I2C设备进行过滤,这些设备都应该是pci的一部分。



无论如何,即使属于pci的设备还有iaioi2c.inf文件中指定的其他硬件ID以及英特尔凌动E3800 fa的数据表mily。



在那里,它说(在第81页 - PCI配置空间)七个I2C端口的设备ID为0F41h-0F47h。



因此,I2C端口应具有类似的HW ID(也在iaioi2c.inf文件中指定):



PCI \VEN_8086& DEV_0F41



但打印设备界面的设备路径时的输出是这样的:



PCI\VEN_8086&安培; DEV_0F4C&安培; SUBSYS_0F4C8086&安培; REV_11#3及11583659&安培0安培; E2#{<第类GUID>}



&NBSP ; b


所以我的问题是:



1.我的手术错了还是遗失了什么?



2.如果我使用iaioi2c.inf文件中定义的GUID类,为什么还要获得I2C端口的其他HW ID?




包含头文件和软件开发人员手册的驱动程序包可在此处找到:



https://开头d ownloadcenter.intel.com/download/24548



英特尔原子E3800系列的数据表可以在这里找到:



https://www.intel.com/content/www/us/en/embedded/products/bay-trail/atom-e3800-family-datasheet.html





$
谢谢! (仅用于阅读所有这些内容)



 

$
Sam

The problem was, that there were no device information elements with that GUID, so I took a look into setup information file used to install the I2C controller driver (iaioi2c.inf).

There is also a ClassGuid defined, but it does not correspond to the one in the header file.

Therefore I tried the other GUID and then I could find several device information elements that use this identifier and created an interface for each to get the device paths.

Those paths where either part of root, acpi or pci which already confuses me since I thought I was only filtering for I2C devices which should all be part of pci.

Anyway even the devices being part of pci had other hardware Id's than specified in the iaioi2c.inf file and the datasheet of the Intel Atom E3800 family.

There, it says (on page 81 - PCI configuration space) the seven I2C ports have the device IDs 0F41h-0F47h.

Hence, the I2C ports should have HW IDs like that (which are also specified in the iaioi2c.inf file):

PCI\VEN_8086&DEV_0F41

But the output when printing the device path of an device interface I got was something like this:

PCI\VEN_8086&DEV_0F4C&SUBSYS_0F4C8086&REV_11#3&11583659&0&e2#{<the class GUID>}

 

So my questions are:

1. Is my procedure wrong or is there anything missing?

2. Why do I get other HW IDs of the I2C ports if I use the class GUID defined in the iaioi2c.inf file?


The driver package including the header files and the software developer's manual can be found here:

https://downloadcenter.intel.com/download/24548

The datasheet of the Intel atom E3800 series can be found here:

https://www.intel.com/content/www/us/en/embedded/products/bay-trail/atom-e3800-family-datasheet.html



Thank you! (Only for reading all this stuff)

 

Sam

推荐答案

没有太多细节:这看起来完全错误。很多年前,我写了一个行为相同的枚举函数 作为其他API枚举函数(例如EnumWindows):

without going too much into detail: This looks completely wrong. Many years ago, I wrote an enumerator function that behaves the same way  as other API enum function (EnumWindows, for example):

typedef BOOL (CALLBACK * ENUMDEVICEINTERFACESCALLBACKPROC)(PCTSTR pszDeviceName, void* ctx);

HRESULT EnumDeviceInterfaces(const GUID* pGuidItf, ENUMDEVICEINTERFACESCALLBACKPROC CallbackProc, void* pCtx)
{
    HRESULT hr = S_OK;
    HDEVINFO hDevInfo = SetupDiGetClassDevs(pGuidItf, nullptr, nullptr, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);

    if(hDevInfo)
    {
        BOOL blContinue = TRUE;
        SP_DEVICE_INTERFACE_DATA spdid;
        spdid.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

        for(DWORD idx = 0; SetupDiEnumDeviceInterfaces(hDevInfo, nullptr, pGuidItf, idx, &spdid); ++idx)
        {
            DWORD dwSize = 0;
            SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, nullptr, 0, &dwSize, nullptr);

            if((dwSize) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
            {
                SP_DEVICE_INTERFACE_DETAIL_DATA* pspdidd = reinterpret_cast<SP_DEVICE_INTERFACE_DETAIL_DATA*>(malloc(dwSize));
                pspdidd->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

                if(SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, pspdidd, dwSize, &dwSize, nullptr))
                {
                    blContinue = CallbackProc(pspdidd->DevicePath, pCtx);
                }
                else
                {
                    hr = HRESULT_FROM_SETUPAPI(GetLastError());
                }

                free(pspdidd);
            }
            else
            {
                hr = HRESULT_FROM_SETUPAPI(GetLastError());
            }

            if(!blContinue)
                break;
        }

        SetupDiDestroyDeviceInfoList(hDevInfo);
    }
    else
    {
        hr = HRESULT_FROM_SETUPAPI(GetLastError());
    }

    return(hr);
}

现在你所要做的就是实现回调函数,例如:

All you have to do now is to implement the callback function, for example:

BOOL CALLBACK EnumDevInterfacesCB(PCTSTR pszDeviceName, void* pCtx)
{
    // CreateFile(pszDeviceName, ...);
    MessageBox(nullptr, pszDeviceName, nullptr, MB_OK);
    return(TRUE);
}

然后你可以调用枚举函数:

You can then call the enum function:

HRESULT hr = EnumDeviceInterfaces(&I2C_LPSS_INTERFACE_GUID, EnumDevInterfacesCB, nullptr);

if(FAILED(hr))
{
    PTSTR pError = nullptr;

    if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, static_cast<DWORD>(hr), 0, reinterpret_cast<PTSTR>(&pError), 0, nullptr))
    {
        MessageBox(nullptr, pError, nullptr, MB_OK);
        LocalFree(pError);
    }
}

这有效吗?


这篇关于如何使用Win API函数与Intel Atom E3800系列的I2C驱动程序通信?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-24 12:26