阅读:4141回复:2
显卡I2C端口再讨论!
以前有个帖子:如何利用显卡的VGA口上的I2C总线来传送数据。给了我很大的帮助,在此感谢那些提供宝贵意见的人们!我根据那个帖子给出的提示作了很长时间的研究,但是成效甚微。现在我能够找到显卡驱动中的I2C接口函数的指针:i2cOpen和i2cAccess。但是,这两个函数却不能使用,总是返回0xc00000c2这个硬件错误。我用的显卡是ATI RADEON 9200,操作系统是windows xp。下面是我的例子代码:
NTSTATUS FindI2CInterfaceProvider(I2CINTERFACE * pI2CInterface) { PWSTR pInterfaceList; PWSTR pInterfaceListWalk; // I2CINTERFACE * pI2CInterface; NTSTATUS status; // // Enumerate buses DbgPrint("FindI2CInterfaceOnDisplayDevice ....\n"); // // DbgPrint("IoGetDeviceInterfaces success!pInterfaceList=%d \n",0xffff & *pInterfaceList); pInterfaceListWalk = pInterfaceList; // pI2CInterface = ExAllocatePool(PagedPool, sizeof(I2CINTERFACE)); // if (!pI2CInterface) { // DbgPrint("pI2CInterface can not be ExAllocatePool! \n"); // return STATUS_INSUFFICIENT_RESOURCES; // } DbgPrint("pI2CInterface can be ExAllocatePool success!\n"); if(*pInterfaceListWalk != UNICODE_NULL) { PDEVICE_OBJECT pTargetDevice; UNICODE_STRING TargetDeviceName; PIRP pIrp; KEVENT Event; IO_STATUS_BLOCK Iosb; PIO_STACK_LOCATION pIrpSp; PFILE_OBJECT pFileObject; // // Create counted string version of // target device name. // RtlInitUnicodeString(&TargetDeviceName, pInterfaceList); KeInitializeEvent(&Event, NotificationEvent, FALSE); // // Get a pointer to its Device object // status = IoGetDeviceObjectPointer( &TargetDeviceName, FILE_ALL_ACCESS, &pFileObject, &pTargetDevice); if (!NT_SUCCESS(status)) { DbgPrint("IoGetDeviceObjectPointer() failed!\n"); return status; } DbgPrint("IoGetDeviceObjectPointer() success!\n "); // // Decrement reference count on unused // File object // ObDereferenceObject(pFileObject); // RtlZeroMemory(pI2CInterface, sizeof(I2CINTERFACE) ); pIrp = IoAllocateIrp(pTargetDevice->StackSize, FALSE); if(pIrp == NULL) { DbgPrint("IoAllocateIrp can not allocate IRP!\n"); return status; } pIrpSp = IoGetNextIrpStackLocation(pIrp); if(pIrpSp == NULL) { DbgPrint("IoGetNextIrpStackLocation can not allocate NextStack!\n"); return status; } pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED; pIrpSp->MajorFunction = IRP_MJ_PNP; pIrpSp->MinorFunction = IRP_MN_QUERY_INTERFACE; pIrpSp->Parameters.QueryInterface.InterfaceType = (struct _GUID *)&GUID_I2C_INTERFACE; pIrpSp->Parameters.QueryInterface.Size = sizeof(I2CINTERFACE); pIrpSp->Parameters.QueryInterface.Version = 1; pIrpSp->Parameters.QueryInterface.Interface = (PINTERFACE)pI2CInterface; pIrpSp->Parameters.QueryInterface.InterfaceSpecificData = NULL; IoSetCompletionRoutine(pIrp, SynchFunction, &Event, TRUE, TRUE, TRUE); // // Call SMB CMI driver to get segment/device information // status = IoCallDriver(pTargetDevice, pIrp); if (status == STATUS_PENDING) { // Wait for the IRP to be completed, then grab the real status code KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL); status = pIrp->IoStatus.Status; } DbgPrint("IRP_MN_QUERY_INTERFACE has been send\n"); if (NT_SUCCESS(status)) { // we've got a device, so create a device object and save // the slave address and lower device object pointer // to the device extension DbgPrint("We have find one I2C Interface!\n"); if((pI2CInterface->i2cOpen ==NULL) || (pI2CInterface->i2cAccess == NULL)) { DbgPrint("I2c Interface can not be opened!\n"); } else{ DbgPrint("I2c Interface can be opened!\n"); g_pi2creference->m_pdoDriver = pTargetDevice; //HERN :get device object of display adapter. // g_pi2creference->m_i2cProviderInterface = * pI2CInterface; // RtlCopyMemory(g_pi2creference->m_i2cProviderInterface,pI2CInterface,sizeof(I2CINTERFACE)); g_pi2creference->m_ulI2CAccessClockRate = I2C_FIXED_CLOCK_RATE; DbgPrint("I2c Interface can be copyed to g_pi2creference!\n"); // DbgPrint("I2c Interface g_pi2creference->m_ulI2CAccessClockRate = %d\n",g_pi2creference->m_ulI2CAccessClockRate); } } // // DbgPrint("status is %x\n",status); IoFreeIrp(pIrp); // // Advance to next interface string // // pInterfaceListWalk += wcslen(pInterfaceListWalk) + 1; //HERN we get first device only,and not mention the others. } // ExFreePool(pI2CInterface); ExFreePool(pInterfaceList); return status; } 这部分代码可以成功找到显卡驱动导出的I2C函数借口指针,但是,I2C 函数却无法使用,总是返回错误代码0xc00000c2。我已经仔细研究过ddk中给出的这部分帮助文档。但是却找不到解决方法。我在网上看到有人遇到相同的问题。在此,恳请各位给与宝贵意见。 |
|
沙发#
发布于:2008-04-16 15:45
我知道我现在使用的显卡肯定支持 IRP_MN_QUERY_INTERFACE GUID_I2C_INTERFACE。我不知道是不是xp 操作系统修改了这部分的要求,还是其他的原因。我也研究过现在网上的WinI2C-DDC,我发现,那个东东的编程思想是按照WinIo的思路作的。结合linux版本的I2C通信程序,可以实现windows 版本的I2C 通信程序。但是,我不明白为什么明确给出的接口为什么不能用。
我的联系方式:37279691(qq) (msn): liuzhu800613@hotmail.com email:liuzhu800613@126.com |
|
板凳#
发布于:2008-04-27 02:42
是的,你的思路是对的,可能是你没有处理好
WINI2C-DDC确实也是通过IO方式来实现的。 |
|
|