Dump brightness of external monitor through DDC/CI communication (i2c communication)
Dump brightness of external monitor through DDC/CI communication (i2c communication)
- Subject: Dump brightness of external monitor through DDC/CI communication (i2c communication)
- From: email@hidden
- Date: Mon, 21 Feb 2011 16:58:09 +0100
Starting from these two examples provided by Apple:
http://www.opensource.apple.com/source/IOGraphics/IOGraphics-383.1/tools/i2cexample.c
http://www.opensource.apple.com/source/IOGraphics/IOGraphics-383.1/tools/itvview.c
I have been able to build a program that can set the brightness of my BenQ
external monitor programmatically using DDC/CI communication. This is the
code:
#include <IOKit/IOKitLib.h>
#include <ApplicationServices/ApplicationServices.h>
#include <IOKit/i2c/IOI2CInterface.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void BrightnessModify( IOI2CConnectRef connect, int bright)
{
kern_return_t kr;
IOI2CRequest request;
UInt8 data[128];
bzero( &request, sizeof(request));
request.commFlags = 0;
request.sendAddress = 0x6E;
request.sendTransactionType = kIOI2CSimpleTransactionType;
request.sendBuffer = (vm_address_t) &data[0];
request.sendBytes = 7;
data[0] = 0x51;
data[1] = 0x84;
data[2] = 0x03;
data[3] = 0x10;
data[4] = 0x64 ;
data[5] = bright ;
data[6] = 0x6E ^ data[0] ^ data[1] ^ data[2] ^ data[3]^ data[4]^
data[5];
request.replyTransactionType = kIOI2CNoTransactionType;
request.replyBytes = 0;//128;
kr = IOI2CSendRequest( connect, kNilOptions, &request );
assert( kIOReturnSuccess == kr );
if( kIOReturnSuccess != request.result)
return;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void BrightnessMain(int level)
{
kern_return_t kr;
io_service_t framebuffer, interface;
IOOptionBits bus;
IOItemCount busCount;
//int level;
framebuffer = CGDisplayIOServicePort(CGMainDisplayID());
{
io_string_t path;
kr = IORegistryEntryGetPath(framebuffer, kIOServicePlane, path);
assert( KERN_SUCCESS == kr );
kr = IOFBGetI2CInterfaceCount( framebuffer, &busCount );
assert( kIOReturnSuccess == kr );
for( bus = 0; bus < busCount; bus++ )
{
IOI2CConnectRef connect;
kr = IOFBCopyI2CInterfaceForBus(framebuffer, bus, &interface);
if( kIOReturnSuccess != kr)
continue;
kr = IOI2CInterfaceOpen( interface, kNilOptions, &connect );
IOObjectRelease(interface);
assert( kIOReturnSuccess == kr );
if( kIOReturnSuccess != kr)
continue;
BrightnessModify(connect, level);
IOI2CInterfaceClose( connect, kNilOptions );
}
}
return(0);
}
and it works perfectly.
What I am not able to achieve is to dump/read the actual brightness value.
As far as I can't have access to VESA specification about DDC/CI, I read
here;
http://www.boichat.ch/nicolas/ddcci/specs.html
and I wrote this program:
#include <IOKit/IOKitLib.h>
#include <ApplicationServices/ApplicationServices.h>
#include <IOKit/i2c/IOI2CInterface.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void BrightnessRead( IOI2CConnectRef connect)
{
kern_return_t kr;
IOI2CRequest request;
UInt8 data[128];
UInt8 inData[9];
int i;
bzero( &request, sizeof(request));
request.commFlags = 0;
request.sendAddress = 0x6E;
request.sendTransactionType = kIOI2CSimpleTransactionType;
request.sendBuffer = (vm_address_t) &data[0];
request.sendBytes = 5;
request.minReplyDelay = 6000000;
data[0] = 0x51;
data[1] = 0x82;
data[2] = 0x01;
data[3] = 0x10;
data[4] = 0x6E ^ data[0] ^ data[1] ^ data[2] ^ data[3];
request.replyTransactionType = kIOI2CDDCciReplyTransactionType;
request.replyAddress = 0x6F;
request.replySubAddress = 0x51;
request.replyBuffer = (vm_address_t) &inData[0];
request.replyBytes = 9;
bzero( &inData[0], request.replyBytes );
kr = IOI2CSendRequest( connect, kNilOptions, &request );
assert( kIOReturnSuccess == kr );
if( kIOReturnSuccess != request.result)
return;
for (i=0; i<9; i++) {
printf(" 0x%x ",inData[i]);
}
printf("n");
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int main( int argc, char * argv[] )
{
kern_return_t kr;
io_service_t framebuffer, interface;
IOOptionBits bus;
IOItemCount busCount;
framebuffer = CGDisplayIOServicePort(CGMainDisplayID());
{
io_string_t path;
kr = IORegistryEntryGetPath(framebuffer, kIOServicePlane, path);
assert( KERN_SUCCESS == kr );
kr = IOFBGetI2CInterfaceCount( framebuffer, &busCount );
assert( kIOReturnSuccess == kr );
for( bus = 0; bus < busCount; bus++ )
{
IOI2CConnectRef connect;
kr = IOFBCopyI2CInterfaceForBus(framebuffer, bus, &interface);
if( kIOReturnSuccess != kr)
continue;
kr = IOI2CInterfaceOpen( interface, kNilOptions, &connect );
IOObjectRelease(interface);
assert( kIOReturnSuccess == kr );
if( kIOReturnSuccess != kr)
continue;
BrightnessRead(connect);
IOI2CInterfaceClose( connect, kNilOptions );
}
}
exit(0);
return(0);
}
The program has a very strange behavior. I try to explain what it does.
Suppose I set a brightnes value of 50 from the monitor OSD or from the first
program I posted. When I launch the program for reading the brightness value
it behaves quite randomly! Sometimes it gives me the right value, sometimes
not. I mean, if I hold the brightness at a fixed value and I launch the
program 10 times, it gives me different values! Sometimes they are correct
and sometimes they are not.
Can you help me on pointing me in the right direction?
I really don't know more where to look..
--
Caselle da 1GB, trasmetti allegati fino a 3GB e in piu' IMAP, POP3 e SMTP
autenticato? GRATIS solo con Email.it: http://www.email.it/f
Sponsor:
Apri Conto Corrente Arancio entro il 28 febbraio 2011 e ricevi 100 euro da
spendere su Media World compra online. Aprilo adesso!
Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=11251&d=20110221
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Accessibility-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden