Hi,
I am using Intel's NUC Baytrail device and have connected a temperature sensor to the I2C interface.
Platform: Intel NUC Baytrail device
Operating System: Windows 7
Testing interface: I2C
Situations handled:
1. Changed BIOS from UEFI to Secured mode
2. Step 1 helped to show the I2C device in the device manager.
3. Writing a test application program to perform read / write operation
4. Createfile() returns the handle of the temperature sensor device
5. The write / read operation does not succeed.
Below is the code for the same.
// LocalPortTestApp.cpp : Defines the entry point for the console application.
//
//
#include "stdafx.h"
#include <objbase.h>
#include <initguid.h>
#include "I2Cpublic.h"
#include <SetupAPI.h>
#include <iostream>
#include <algorithm>
#include <combaseapi.h>
#include <Windows.h>
#include <RegStr.h>
#include <WinBase.h>
#include <tchar.h>
#include <strsafe.h>
#include <winioctl.h>
using namespace std;
/**
* These are the generic rights used in serial com port open
*/
#define S_GENERIC_READ (0x80000000UL) ///<Windows Constant
#define S_GENERIC_WRITE (0x40000000UL) ///<Windows Constant
#define S_GENERIC_EXECUTE (0x20000000UL) ///<Windows Constant
#define S_GENERIC_ALL (0x10000000U1L) ///<Windows Constant
/**
* Constants used in serial com port open
*/
#define S_CREATE_NEW 1UL ///<Windows Constant
#define S_CREATE_ALWAYS 2UL ///<Windows Constant
#define S_OPEN_EXISTING 3UL ///<Windows Constant
#define S_OPEN_ALWAYS 4UL ///<Windows Constant
#define S_TRUNCATE_EXISTING 5UL ///<Windows Constant
/*****************************************************************************************************
* GENERAL TYPEDEF
****************************************************************************************************/
typedef unsigned char sUINT8; ///<8 bit variable
typedef signed char sINT8; ///<7 bit variable
typedef unsigned char* sUINT8P; ///<8 bit variable pointer
typedef const unsigned char* sCUINT8P; ///<8 bit constant variable pointer
typedef short int sINT16; ///<15 bit variable
typedef unsigned short sUINT16; ///<16 bit variable
typedef unsigned short* sUINT16P; ///<16 bit variable pointer
typedef long sINT32; ///<31 bit variable
typedef unsigned long sUINT32; ///<32 bit variable
typedef unsigned long* sUINT32P; ///<32 bit variable pointer
typedef const unsigned long* sCUINT32P; ///<32 bit variable pointer
typedef float sFLOAT; ///<float variable
typedef double sDOUBLE; ///<double variable
typedef unsigned char sBOOL; ///<8 bit variable
typedef void* sVOIDP; ///<memory pointer
typedef const void* sCVOIDP; ///<memory pointer
/**
* ENUM for ERROR CODE which will be return value
*/
enum returnStatus
{
S_SUCCESS = 0, ///<Task completed successfully
S_ERROR_FAILURE = 1, ///<Task is not completed, due to some reason
S_ERROR_PORT_OPEN = 2, ///<Error occurred while opening PC channel driver port
S_ERROR_PORT_CLOSE = 3, ///<Error occurred while closing PC channel driver port
S_ERROR_CONFIG_PORT = 4, ///<Error occurred while configuring PC channel driver port
S_ERROR_READ_BUFFER = 5, ///<Error occurred while reading data from internal port buffer
S_ERROR_WRITE_BUFFER = 6, ///<Error occurred while writing data to internal port buffer
S_ERROR_ARGUMENT = 7, ///<API argument is not valid
S_ERROR_CHANNEL_INVALID = 8, ///<Proper channel is not selected
S_ERROR_TIME_OUT = 9, ///<Waiting Time is over
S_ERROR_SEND = 10, ///<Error occurred while sending command to Sunset Pass Module, due to lack of acknowledgment from Sunset Pass Module or timeout.
S_ERROR_SEQUENCE = 11, ///<Violating task sequence I.e. configure then open etc.
S_ERROR_PORT_ACQUIRED = 14, ///<Error occurred while trying to acquire handle, acquired by else before and not released yet
S_ERROR_HANDLE_MISMATCH = 15, ///<Error occurred while port handle supplied as argument is not matching with handle acquired
S_BOOT_MODE = 16 ///<Microcontroller is in Boot Mode
};
#define BUF_SIZE 50
int main(int argc, char* argv[])
{
returnStatus eResult = S_ERROR_PORT_OPEN;
GUID *i2cGuid = const_cast<GUID *>(&I2C_LPSS_INTERFACE_GUID);
HDEVINFO hDevInfo;
SP_DEVINFO_DATA devInfoData;
HANDLE i2c_Handle = HANDLE(NULL); ///<handle of i2c port to access it
hDevInfo = SetupDiGetClassDevs(i2cGuid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES);
if(hDevInfo == INVALID_HANDLE_VALUE)
{
return S_ERROR_FAILURE;
}
else
{
std::cout << "SetupDiGetClassDevs is Successfull.\n";
}
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
SP_DEVICE_INTERFACE_DATA devInterfData = { 0 };
devInterfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
DWORD i = 0;
if(SetupDiEnumDeviceInterfaces(hDevInfo, NULL, i2cGuid, i, &devInterfData))
{
DWORD size = 0;
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfData, NULL, 0, &size, 0))
{
if (GetLastError() == ERROR_NO_MORE_ITEMS)
{
eResult = S_SUCCESS;
while(1);
return 0;
}
PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, size);
pInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfData, pInterfaceDetailData, size, &size, &devInfoData))
{
std :: cout << "SetupDiGetDeviceInterfaceDetail is Failed.\n";
eResult = S_ERROR_FAILURE;
while(1);
return 0;
}
std :: cout << "CreatFile Calling.\n";
std :: cout << "PATH of I2C interface in REGEDIT : "<< pInterfaceDetailData->DevicePath<<endl;
std :: cout <<endl;
i2c_Handle = CreateFile(LPCWSTR(pInterfaceDetailData->DevicePath),
DWORD(GENERIC_READ | GENERIC_WRITE),
DWORD(FILE_SHARE_READ | FILE_SHARE_WRITE),
LPSECURITY_ATTRIBUTES(NULL),
DWORD(OPEN_EXISTING),
DWORD(FILE_FLAG_OVERLAPPED),
(HANDLE)NULL);
//Validation for correct open port
if(i2c_Handle == INVALID_HANDLE_VALUE)
{
std::cout << " Port Open Error : " << GetLastError() <<endl;
}
else
{
std :: cout << "Creatfile is successfull..... = "<< i2c_Handle << endl;
std::cout << endl;
}
}
}
else
{
char ch;
std::cout << "1... Press any key and then ENTER to exit\n";
std::cin >> ch;
return 0;
}
//HANDLE hEvent;
DWORD varEventResult;
//HANDLE varEventObjectHandle = 0;
/*Overlapped1.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(Overlapped1.hEvent)
{
std::cout <<"Create Event Successfull - 1." <<endl;
}
else
{
std::cout <<"Create event failed with error : "<< GetLastError() <<endl;
}*/
OVERLAPPED Overlapped1;
/*Overlapped1.OffsetHigh = 0;
Overlapped1.Offset = 0;*/
memset(&Overlapped1, 0, sizeof(Overlapped1));
BOOL status;
I2C_SINGLE_TRANSMISSION writeTransmission;
UCHAR writeBuf[2] = {0x90,0x00};
UCHAR readBuf[BUF_SIZE] = {};
UINT16 slaveAdr = 0x90;
DWORD bytesReturned = 0;
writeTransmission.Address = slaveAdr;
writeTransmission.AddressMode = AddressMode7Bit;
writeTransmission.BusSpeed = I2C_BUS_SPEED_400KHZ;
writeTransmission.DataLength = sizeof(writeBuf);
writeTransmission.pBuffer = writeBuf;
status = DeviceIoControl(i2c_Handle,
(DWORD)IOCTL_I2C_EXECUTE_WRITE,
&writeTransmission,
(DWORD)sizeof(writeTransmission),
NULL,
0,
NULL,
(LPOVERLAPPED)&Overlapped1);
std::cout << "Write Transmission....."<<endl;
std::cout << "Slave Address : "<<slaveAdr<<endl;
std::cout << "Status : "<< status << endl << "Get-Last-Error-Code : "<< GetLastError() << endl;
std::cout << endl;
Sleep(10);
//varEventResult = WaitForSingleObject(Overlapped1.hEvent, 10000);
if(status || (GetLastError() == ERROR_IO_PENDING))
{
status = GetOverlappedResult(i2c_Handle,
(LPOVERLAPPED)&Overlapped1,
&bytesReturned,
TRUE);
if(status)
{
std::cout << "Write Data : "<< writeBuf[0] << endl;
std::cout << endl;
}
else
{
std::cout << "GetOverlappedResult....1 Failed - Write. "<< GetLastError() << endl;
std::cout << endl;
}
//ResetEvent(Overlapped1.hEvent);
//CloseHandle(Overlapped1.hEvent);
}
else
{
std::cout << "Write Data Failed. "<< endl;
std::cout << endl;
}
std::cout << "--------------------------------------------------------\n\n";
OVERLAPPED Overlapped2;
Overlapped2.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if(Overlapped2.hEvent)
{
std::cout <<"Create Event Successfull - 2." <<endl;
}
else
{
std::cout <<"Create event failed with error : "<< GetLastError() <<endl;
}
Overlapped2.OffsetHigh = 0;
Overlapped2.Offset = 0;
I2C_SINGLE_TRANSMISSION readTransmission;
UINT16 slaveAdr1 = 0x91;
readTransmission.Address = slaveAdr1;
readTransmission.AddressMode = AddressMode7Bit;
readTransmission.BusSpeed = I2C_BUS_SPEED_400KHZ;
readTransmission.DataLength = sizeof(readBuf);
readTransmission.pBuffer = readBuf;
//memset(&Overlapped1, 0, sizeof(Overlapped1));
ResetEvent(Overlapped1.hEvent);
status = DeviceIoControl(i2c_Handle,
(DWORD)IOCTL_I2C_EXECUTE_READ,
NULL,
0,
&readTransmission,
sizeof(readTransmission),
NULL,
(LPOVERLAPPED)&Overlapped2);
Sleep(10);
std::cout << "Read Transmission....."<<endl;
std::cout << "Status : "<< status << endl << "Get-Last-Error-Code : "<< GetLastError() << endl;
std::cout << endl;
varEventResult = WaitForSingleObject(Overlapped2.hEvent, 10000);
if(status || (GetLastError() == ERROR_IO_PENDING))
{
status = GetOverlappedResult(i2c_Handle,
(LPOVERLAPPED)&Overlapped2,
&bytesReturned,
TRUE);
if(status)
{
std::cout << " data is : " << readBuf[0] << endl;
std::cout << endl;
}
else
{
std::cout << "GetOverlappedResult....2 Failed - Read. "<< GetLastError() << endl;
std::cout << endl;
}
//ResetEvent(Overlapped2.hEvent);
CloseHandle(Overlapped2.hEvent);
}
else
{
std::cout << "Read Data Failed. "<< endl;
}
CloseHandle(i2c_Handle);
char ch;
std::cout << "2... Press any key and then ENTER to exit.....\n";
std::cin >> ch;
return 0;
}
Below is the output of the above code:
I would be grateful, If you can help me identify this issue and help resolve.
Thanks in advance of your support.
reg.
-prajose john