ATI Internals

Sběrnice I2C

Všechny obvody v ATI-TV, které je možné softwarově ovládat, používají sběrnici I2C. Její hardwarový popis tady uvádět nebudu, protože je to z programátorského hlediska zbytečné, a hlavně ho neznám :-). Stačí, že je to sériová sběrnice se signály clock a data.

ATI ve svých programech používá pro přístup k I2C knihovnu ATI_I2C.DLL. Dříve jsem ji taky používal, ale pak jsem si všiml, že TV-Online se na ATI_I2C.DLL vůbec neobrací a místo toho používá knihovnu I2CAPI.DLL. Ta je, na rozdíl od ATI_I2C.DLL, umístěná v systémovém adresáři Windows (%WINDIR%\System). Přitom všechny odstatní DLL jsou v \ATI\ATIDESK[\DRIVERS]. Předpokládám tedy, že I2CAPI.DLL je jakási "veřejná" knihovna, která má sloužit vývojářům ke komunikaci s I2C. Navíc jsem se do ní díval, a je to vlastně jen interface, který najde ATI_I2C.DLL, naimportuje z ní patřičné funkce a ty pak volá. To by potvrzovalo předpoklad o public verzi.

Ještě vás chci upozornit, že programuji převážně v Delphi. Proto i všechny deklarace funkcí apod. budu uvádět tak, jak by se použily v Delphi. Myslím ale, že převod do "C" podoby pro vás nebude vůbec žádný problém.

I2CAPI.DLL

Knihovna I2CAPI.DLL exportuje tyto funkce pro práci s I2C:

                         NE-Dump of "I2CAPI.DLL"
...
     Entry   7: I2CREADAFTERRESTART
     Entry   4: I2CCLOSE
     Entry   3: I2COPEN
     Entry   6: I2CWRITE
...
Když se podíváme, s jakými parametry se tyto funkce volají, vyjde nám něco takového:

function I2COPEN(dummy:Word):Word; far; 
  external 'I2CAPI.DLL' name 'I2COPEN';

procedure I2CCLOSE; far; 
  external 'I2CAPI.DLL' name 'I2CCLOSE';

function I2CWRITE(
    xunit:Word; port:Word; 
    wbuffer:Pointer; wcount:Word):Word; far; 
  external 'I2CAPI.DLL' name 'I2CWRITE';

function I2CREADAFTERRESTART(
    xunit:Word; port:Word; 
    rbuffer:Pointer; rcount:Word;
    wbuffer:Pointer; wcount:Word):Word; far;
  external 'I2CAPI.DLL' name 'I2CREADAFTERRESTART';
Důležité jsou jen funkce I2CWRITE a I2CREADAFTERRESTART. I2COPEN a I2CCLOSE totiž v aktuální verzi (5.0) nedělají vůbec nic. Resp. I2CCLOSE skutečně nedělá nic, a I2COPEN pouze vrátí parametr dummy, který jí byl předán :-).

Takže teď k těm dvěma důležitým funkcím:


function I2CWRITE(xunit:Word; port:Word; wbuffer:Pointer; wcount:Word):Word;
Pošle data na sběrnici I2C.
function I2CREADAFTERRESTART(xunit:Word; port:Word; rbuffer:Pointer; rcount:Word; wbuffer:Pointer; wcount:Word):Word;
Načte data ze sběrnice I2C, případně na ni ještě předtím pošle data (obvykle adresu registru, ze kterého se bude číst). Pokud chcete z I2C pouze číst, nastavte wcount na nulu.
Ukázkový unit v Delphi pro práci s I2CAPI.DLL:

unit I2C_API;

interface

uses
  SysUtils, WinTypes, WinProcs;

type
 TI2CBuffer = record
  a:Word;            {+0 (0)}
  port:Word;            {+2 (port)}
  retval:Word;            {+4 (return value -- 0 = OK)}
  writeCount:Word;            {+6 (delka)}
  readCount:Word;             {+8 (0)}
  writeBuf:Pointer;         {ofs=+0a, seg=+0c}
  readBuf:Pointer;
 end;

procedure I2C_Open;
procedure I2C_Close;
function I2C_write(port:Byte; co:String):Word;
function I2C_read(port:Byte; wbuf:String; co:Pointer; delka:Integer):Word;

implementation

function I2COPEN(dummy:Word):Word; far; external 'I2CAPI.DLL' name 'I2COPEN';
procedure I2CCLOSE; far; external 'I2CAPI.DLL' name 'I2CCLOSE';
function I2CWRITE(xunit:Word; port:Word; wbuffer:Pointer; wcount:Word):Word; far; external 'I2CAPI.DLL' name 'I2CWRITE';
function I2CREADAFTERRESTART(xunit:Word; port:Word; rbuffer:Pointer; rcount:Word;
                             wbuffer:Pointer; wcount:Word):Word; far;
                             external 'I2CAPI.DLL' name 'I2CREADAFTERRESTART';

procedure I2C_Open;
var
 W:Word;
begin
 W:=I2COPEN(0);
end;

procedure I2C_Close;
begin
 I2CCLOSE; 
end;

function I2C_write(port:Byte; co:String):Word;
begin
 I2C_write := I2CWRITE(0, port, @co[1], Length(co)); 
end;

function I2C_read(port:Byte; wbuf:String; co:Pointer; delka:Integer):Word;
begin
 I2C_read := I2CREADAFTERRESTART(0, port, co, delka, @wbuf[1], Length(wbuf)); 
end;

end.
To by bylo pro začátek všechno. Odkazy na popisy jednotlivých I2C obvodů jsou na úvodní straně.

homepage