5 Replies Latest reply on Aug 8, 2017 1:56 PM by PaulDemet

    Problem Opening I2C Device on E3800

    PaulDemet Community Member

      I have written the following code in an attempt to use the iaioi2c.sys I2C driver on the E3800 Bay Trail. Everything appears good until I try to execute CreateFile which fails with an ERROR_FILE_NOT_FOUND code. What am I doing wrong?

       

              HDEVINFO DeviceInfoSet;

              SP_DEVINFO_DATA DeviceInfoData;

              SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;

              PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = NULL;

              PDWORD requiredSize;

              DWORD Index = 0;

              HANDLE tempHandle;

              WCHAR *i2cDevice = I2C_CONTROLLER_NUM;

              DWORD LastError;

              DWORD status = SUCCESS;

       

              DeviceInfoSet = SetupDiGetClassDevs((GUID*)&I2C_LPSS_INTERFACE_GUID, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

       

              if (DeviceInfoSet == INVALID_HANDLE_VALUE)

                  return status = INVALID_HANDLE;

       

              DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

       

              SetupDiEnumDeviceInfo(DeviceInfoSet, Index, &DeviceInfoData);

       

              while (SetupDiEnumDeviceInfo(DeviceInfoSet, Index, &DeviceInfoData))

              {

                  DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

                  SetupDiCreateDeviceInterface(DeviceInfoSet, &DeviceInfoData, &DeviceInfoData.ClassGuid, NULL, 0, &DeviceInterfaceData);

       

                  // call the first time to get required buffer size

                  requiredSize = (PDWORD)malloc(sizeof(DWORD));

                  status = SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &DeviceInterfaceData, NULL, 0, requiredSize, NULL);

                  LastError = GetLastError();

       

                  if (status == FALSE && LastError != ERROR_INSUFFICIENT_BUFFER)

                  {

                      SetupDiDestroyDeviceInfoList(DeviceInfoSet);

                      return LastError;

                  }

       

                  // allocate required buffer

                  if (requiredSize)

                      DeviceInterfaceDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(*requiredSize);

                     

                  if (DeviceInterfaceDetailData == NULL)

                  {

                      SetupDiDestroyDeviceInfoList(DeviceInfoSet);

                      return status = INSUFFICIENT_MEMORY;

                  }

       

                  // call the second time to get detailed info

                  DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

                  status = SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &DeviceInterfaceData, DeviceInterfaceDetailData, *requiredSize, NULL, &DeviceInfoData);

       

                  if (status == FALSE)

                  {

                      SetupDiDestroyDeviceInfoList(DeviceInfoSet);

                      return GetLastError();

                  }

       

                  // check for i2c controller #1

                  if (wcsstr(DeviceInterfaceDetailData->DevicePath, i2cDevice) != NULL)

                      break;

       

                  Index++;

              }

       

              tempHandle = CreateFile(DeviceInterfaceDetailData->DevicePath,

                  GENERIC_READ | GENERIC_WRITE,

                  0,

                  NULL,

                  OPEN_EXISTING,

                  FILE_FLAG_OVERLAPPED,

                  NULL);

        • Re: Problem Opening I2C Device on E3800
          PaulDemet Community Member

          Should have included this. The value I receive for DeviceInterfaceDetailData->DevicePath is:

           

             L"\\\\?\\pci#ven_8086&dev_0f41&subsys_72708086&rev_11#3&11583659&0&c1#{4d36e97d-e325-11ce-bfc1-08002be10318}"

          • Re: Problem Opening I2C Device on E3800
            Carlos_A Brown Belt

            Hello, PaulDemet:

             

            Thank you for contacting Intel Embedded Community.

             

            In order to be on the same page, we would like to address the following questions:

             

            Could you please tell us in a detailed way the procedure that you have followed to implement this driver? Please include documents and their numbers, reference drivers, where they can be found, also download links.

             

            Could you please inform us if the affected design is a third party or has been developed by you? In case that it is a third party design, please give us all the information related to it.

             

            Could you please let us know the Operating System (OS) that is experiencing this problem?

             

            Could you please give us the part numbers of the processor and chipset related to the cited situation?

             

            Please let us know all the information that should answer the previous consultations.

             

            Thanks for your cooperation to solve this inconvenience.

             

            Best regards,

            Carlos_A.

              • Re: Problem Opening I2C Device on E3800
                PaulDemet Community Member

                I am using the software and documentation found in the 334397-002 Intel Atom E3800 Win7 IO Drivers MR4_Non Secure.zip file. I found hem here:

                 

                      Download Intel® Embedded Drivers for Windows* 7 (32-bit and 64-bit)

                 

                This is based on a design we did internally. It uses the E3845 processor.

                 

                It is using WES7 - 64 bit.

                 

                I am trying to control a device that s connected to one of the I2C controllers in the Bay Trail device. I am following the suggestions found in the Driver Software Developer's Manual. Specifically this section:

                 

                The I2C driver is opened using the Win32 CreateFile API. To get the device name, use GUID interface exposed by the driver: I2C_LPSS_INTERFACE_GUID, defined in public.h. A device interface class is a way of exporting device an= d driver functionality to other system components, including other drivers, as well as user-mode applications. A driver can register a device interface class, and then enable an instance of the class for each device object to which user-mode I/O requests might be sent.

                 

                Device interfaces are available to both kernel-mode components and user-mode applications. Usermode code can use SetupDiXxx functions to find out about registered, enabled device interfaces. Please refer the following site to get the details about SetupDiXxx functions.

                     http://msdn.microsoft.com/en-us/library/dd406734.aspx

                 

                Since there are more than one I2C controller in BYT-I platform, and they share the same GUID, when user-mode applications open I2C device using SetupDiXxx, they will get a device name list of all I2C controller interfaces. At this time, they should also compare the hardware ID they need to each item of that list, so as to be able open the correct controller they need.