Hirdetés

Új hozzászólás Aktív témák

  • Rover623

    félisten

    A billegtetős móka jól szemlélteti a protokollt.
    Így olvasunk egy byte-ot az I2C buszon...Device az eszköz címe, Index az adatterületről kiolvasni kívánt byte címe.

    I2CStart;
    I2CSendByte (Device-1, False);
    I2CSendByte (Index, False);
    I2CStart;
    I2CSendByte (Device, False);
    Data := I2CReadByte (True);
    I2CStop;

    Az alacsonyszintű rutinok:

    Function I2CSendByte (Data: Byte; Wait: Boolean): Byte; Near;
    Var
    Bit,
    Maszk : Byte;
    Begin
    SetLines (0, 0);
    Maszk := $80;
    For Bit := 0 To 7 Do Begin
    If ( (Data And Maszk) <> 0) Then I2COne
    Else I2CZero;
    Maszk := Maszk ShR 1;
    End; {for}
    If Wait Then Delay (10);
    I2CSendByte := I2CAck;
    End; {I2CSendByte}

    Function I2CReadByte (Last: Boolean): Byte; Near;
    Var
    Bit,
    Data,
    Maszk : Byte;
    Begin
    Data := 0;
    Maszk := $80;
    SetLines (0, 1);
    For Bit := 0 To 7 Do Begin
    SetLines (1, 1);
    If (GetData <> 0) Then Data := Data Or Maszk;
    SetLines (0, 1);
    Maszk := Maszk ShR 1;
    End; {for}
    I2CReadByte := Data;
    If Last Then I2COne
    Else I2CZero;
    End; {I2CReadByte}

    És a lényeg, a "billegtetés":

    Procedure I2CReset; Near;
    Begin
    SetLines (1, 1);
    End; {I2CReset}

    Procedure I2CStart; Near;
    Begin
    SetLines (0, 1);
    SetLines (1, 1);
    SetLines (1, 0);
    SetLines (0, 0);
    End; {I2CStart}

    Procedure I2CStop; Near;
    Begin
    SetLines (0, 0);
    SetLines (1, 0);
    SetLines (1, 1);
    End; {I2CStop}

    Procedure I2COne; Near;
    Begin
    SetLines (0, 1);
    SetLines (1, 1);
    SetLines (0, 1);
    End; {I2COne}

    Procedure I2CZero; Near;
    Begin
    SetLines (0, 0);
    SetLines (1, 0);
    SetLines (0, 0);
    End; {I2CZero}

    Function I2CAck: Byte; Near;
    Begin
    SetLines (0, 1);
    SetLines (1, 1);
    I2CAck := GetData;
    SetLines (0, 1);
    End; {I2CAck}

    A SetLines és a GetData rutinok azok, amiket az adott chipsethez kellett igazítani.
    Pl. a régi VIA chipsetek esetén:

    Procedure VIASetLines (Ctrl, Data: Byte);
    Begin
    Port [I2CBasePort + $42] := (Port [I2CBasePort + $42] And $F9) Or ( (Data ShL 2) Or (Ctrl ShL 1) );
    End; {VIASetLine}

    Function VIAGetData: Byte;
    Begin
    VIAGetData := (Port [I2CBasePort + $44] And $04);
    End; {VIAGetData}

    Azért így, mert a Power Management regiszterkészlet 0x42 (itt lehetett változtatni) és 0x44 (itt lehetett az állapotukat lekérni) byte-ján voltak az I2C vonalak:

    {---------------- VIA bitstring funkciok ----------------------------------}
    (*

    Power Management data area offset 42h

    Bit. Description
    2. I2C data output
    1. I2C clock output

    Power Management data area offset 44h

    Bit. Description
    2. I2C data read
    1. I2C clock read
    *)

    Ha érdekel, elküldhetem a teljes forrást...de szerintem nehezen emészthető...:DDD

Új hozzászólás Aktív témák