Home
Company
Developer Tools
Utilities
Order
Articles
Contacts
Press
Site map
Member zone


Latest news:
September 25, 2008

WinI2C/DDC Lite v3.21 released!


September 24, 2008

WiFi-Manager v4.5 released!


September 15, 2008

Advanced WiFi-Manager v3.0 released!


September 14, 2008

WinI2C/DDC v3.21 released!


August 27, 2008

WinI2C/DDC Lite v3.20 released!


August 21, 2008

WinI2C/DDC v3.20 released!











WinI2C/DDC - Working with I2C bus directly


Contents

Introduction
Monitors enumeration
Using low-level API
Keywords



Introduction

WinI2C/DDC library provides API for working with I2C bus directly, it allows you to communicate with the display device via hardware-specific protocols when necessary and use its advanced capabilities like the firmware upgrading. This article explains how to work with I2C bus directly in Visual Basic, though this sample can be translated to any other language, of course. You can download Visual Basic project for this article at the bottom of the page.




Monitors enumeration

Firstly, it's necessary to call InitDDCHelper function and check its result:

Dim res As Integer
res = InitDDCHelper()
If res <> S_Ok Then 'some error occured
      ShowError (res)
End If


Now we can enumerate available monitors with EnumGetFirst and EnumGetNext functions:
Dim Displays(10) As Long
Dim DispCnt As Long
...
Dim res As Integer
Dim d As EDISP
DispCnt = 0
cbDisplays.Clear
If EnumGetFirst(Displays(DispCnt)) = S_Ok Then 'at least one monitor found
      cbDisplays.AddItem GetMonitorName(Displays(DispCnt))
      DispCnt = DispCnt + 1
      Do While EnumGetNext(Displays(DispCnt)) = S_Ok 'other monitors
            cbDisplays.AddItem GetMonitorName(Displays(DispCnt))
            DispCnt = DispCnt + 1
      Loop
      If cbDisplays.ListCount > 0 Then cbDisplays.ListIndex = 0 'select first monitor
End If


Function "GetMonitorName" just copies the monitor name from Description field of EDISP structure:

Function GetMonitorName(disp As Long) As String
Dim d As EDISP
CopyMemory d, disp, 300 'size of EDISP
s = ""
i = 0
Do While d.Description(i) <> 0
      s = s + Chr$(d.Description(i))
      i = i + 1
Loop
GetMonitorName = s
End Function



Using low-level API

WinI2C/DDC has the following functions for low-level accessing to I2C bus:

TestAddr
ReadI2CBuf
WriteI2CBuf


TestAddr function tests an address on I2C bus, in other words it detects if this address is available or not. I2C bus has a 7-bit address space, for example, IC which returns EDID has address 0x50, DDC address is 0x37. The following code snippet checks if EDID is available:


      res = TestAddr(Displays(disp), &H50)
      If res <> S_Ok Then 'EDID address is not available
            lbEdidAvail.Caption = "NO"
      Else: lbEdidAvail.Caption = "YES"
      End If

The code below tests all I2C addresses:

      For i = 0 To 127
            res = TestAddr(Displays(disp), i)
            h1 = i \ 16
            h2 = i Mod 16
            If res <> S_Ok Then
            lbAddrList.AddItem (ToHex(h1) + ToHex(h2) + " is not available")
            Else: lbAddrList.AddItem (ToHex(h1) + ToHex(h2) + " OK")
            End If
      Next i


ReadI2CBuf and WriteI2CBuf functions allow you to send and receive data over I2C bus. The code below demonstrates how to use these functions to obtain extended EDID data (if a display device supports it) which has 256 bytes length:


' PtrEDID is a pointer to 256 bytes array defined as "Dim EDID(256) As Byte", you can get this pointer via VarPtr function
      Function Read_EDID_256(disp As Long, PtrEDID As Long) As Long
            Dim res As Long
            Dim start As Byte

            start = 0
            res = WriteI2CBuf(Displays(disp), &H50, VarPtr(start), 1, 0)
            If res <> 0 Then
                  ReadEDID256 = res
                  Exit Function
            End If

            res = ReadI2CBuf(Displays(disp), &H50, PtrEDID, &H80, 0)
            If res <> 0 Then
                  ReadEDID256 = res
                  Exit Function
            End If

            start = &H80
            res = WriteI2CBuf(Displays(disp), &H50, VarPtr(start), 1, 0)
            If res <> 0 Then
                  ReadEDID256 = res
                  Exit Function
            End If

            res = ReadI2CBuf(Displays(disp), &H50, PtrEDID + &H80, &H80, 0)
            If res <> 0 Then
                  ReadEDID256 = res
                  Exit Function
            End If

            ReadEDID256 = res
      End Function


Firstly, it's necessary to write one byte (zero) to the address 0x50, it means that EDID will be read from the beginning. Then we read first 128 bytes (0x80) of EDID with ReadI2CBuf function. To read other 128 bytes of EDID we should use WriteI2CBuf function again to specify the data offset (i.e. write one byte 0x80) and then read next 128 bytes of EDID.


Same code for C++:

// PEDID is a buffer for EDID, must be 256 bytes
      ULONG ReadEDID256(PEDISP Device, UCHAR *PEDID)
      {
            UCHAR start = 0;
            ULONG res = 0;

            res = WriteI2CBuf(Device,0x50,&start,sizeof(start), 0);
            if (res) return res;
            res = ReadI2CBuf(Device,0x50,&PEDID[0],0x80, 0);
            if (res) return res;

            start = 0x80;
            res = WriteI2CBuf(Device,0x50,&start,sizeof(start), 0);
            if (res) return res;
            res = ReadI2CBuf(Device,0x50,&PEDID[0x80],0x80, 0);

            return res;
      }


Please download sample VB6 project that enumerates available monitors, scans I2C address space and reads 256 bytes EDID via low-level functions: vbi2c.zip (11KB)




Keywords

I2C bus, Windows, data, EDID, i2c access, I2C hardware, I2C read, I2C write, I2C data, I2C address, I2C port, I2C EDID, I2C protocol, I2C library, I2C example, I2C driver, I2C API, I2C display, I2C interface, I2C monitor, I2C communication, I2C GPU, I2C IO, GPU IO, I2C GPIO, I2C tool, DDC, VESA, DDC/CI, read EDID, DDC for Windows, EDID format, ATI, NVIDIA, Intel, S3, SiS, Matrox, VIA, parse EDID, monitor resolution, get EDID, display, get monitor, library, monitor capabilities, read EDID directly, DDC CI tool, I2C DDC, DDC/CI windows, I2C EDID, Windows DDC, video card, manufacturer ID, DDC/CI software, VCP, CI in Windows, DDC API, VGA, DVI, HDMI, MCCS, get display size, VCP Windows, WinI2C-DDC.



   Copyright ©2002-2007, Nicomsoft Ltd. All Right Reserved.  Privacy Policy  |  Terms of Use