home *** CD-ROM | disk | FTP | other *** search
- PROGRAM i2cscan;
- { Schaut, wer am I²C-Bus angeschlossen ist und zuhört. }
- {$incl "i2c.lib" }
-
- VAR busdelay: Long;
- locked: Boolean;
- allocresult: Byte;
- ch: Char;
- fenster: Text;
-
- FUNCTION hexstr(l: Long; digits: Integer): Str;
- { Zahl mit mindestens <digits> Stellen nach Hex wandeln: }
- VAR i,j,x: Integer;
- s: String[10]; STATIC; { Wichtig! }
- BEGIN
- IF digits<1 THEN digits := 1;
- j := 1;
- FOR i := 7 DOWNTO 0 DO
- IF (i<digits) OR (l SHR (4*i)>0) THEN BEGIN
- x := (l SHR (4*i)) AND $F;
- IF x<10 THEN s[j] := Chr(x+ord('0'))
- ELSE s[j] := Chr(x-10+ord('A'));
- Inc(j);
- END;
- s[j] := #0;
- hexstr := ^s;
- END;
-
- PROCEDURE identify(adr: Byte);
- { Nicht besonders aussagekräftig: die meisten Chips lassen sich auf -zig }
- { verschiedene Adressen einstellen, haben diese dann aber mit mehreren }
- { anderen gemeinsam. }
- BEGIN
- WriteLn(fenster,', might be:');
- IF adr = $20 THEN WriteLn(fenster,'PCF8200: speech synthesizer');
- IF adr = $22 THEN WriteLn(fenster,'SAA5243/SAA5246: teletext decoder');
- IF adr IN [$20,$22] THEN WriteLn(fenster,'SAF1135/SAA4700: VPS decoder');
- IF adr IN [$40..$4E] THEN WriteLn(fenster,'PCF8574: 8 bit IO expander');
- IF adr IN [$70..$7E] THEN WriteLn(fenster,'PCF8574A: 8 bit IO expander');
- IF adr IN [$90..$9E] THEN WriteLn(fenster,'PCF8591: 8 bit DA/AD converter');
- IF adr IN [$70..$76] THEN WriteLn(fenster,'SAA1064: LED driver 2-4 × 8');
- IF adr IN [$70,$72] THEN WriteLn(fenster,'PCF8576: LCD driver 1-4 × 40');
- IF adr = $74 THEN WriteLn(fenster,'PCF8577: LCD driver 1-2 × 32');
- IF adr = $76 THEN WriteLn(fenster,'PCF8577A: LCD driver 1-2 × 32');
- IF adr IN [$7C,$7E] THEN WriteLn(fenster,'PCF8566: LCD driver 1-4 × 24');
- IF adr IN [$78,$7A] THEN BEGIN
- WriteLn(fenster,'PCF8578: LCD dot matrix driver 32×8, 24×16, 16×24 or 8×32,');
- WriteLn(fenster,' possibly with one or more PCF8579 (40 extra columns)');
- END;
- IF adr IN [$A0..$AE] THEN WriteLn(fenster,'PCF8570/PCF8571: 256/128 byte SRAM');
- IF adr IN [$A0..$AE] THEN WriteLn(fenster,'PCF8581/PCF8582: 256/128 byte EEPROM');
- IF adr IN [$B0..$BE] THEN WriteLn(fenster,'PCF8570C: 256 byte SRAM');
- IF adr IN [$D0..$D6] THEN WriteLn(fenster,'PCF8573: clock/calendar');
- IF adr IN [$A0,$A2] THEN WriteLn(fenster,'PCF8583: clock/calendar and 256 byte SRAM');
- IF adr IN [$80..$86] THEN WriteLn(fenster,'SAA1300: power output 5×85 mA');
- IF adr = $88 THEN WriteLn(fenster,'TDA8442: DAC & switch for color decoder');
- IF adr IN [$90..$9E] THEN WriteLn(fenster,'TDA8440: AV input selector');
- IF adr IN [$40..$4E] THEN WriteLn(fenster,'TDA8444: 8 × 6 bit D/A converter');
- END;
-
- PROCEDURE scan(verbose: Boolean);
- VAR rd,wr: Boolean;
- status: Long;
- i,buffer: Integer;
- LIBRARY DosBase:
- -204: FUNCTION WaitForChar(D1: Long; D2: Long): Boolean;
- END;
- FUNCTION report(code: Long): Boolean;
- { Fehlermeldung ausgeben, True, wenn wirklicher Fehler }
- BEGIN
- IF (code AND $FF)=0 THEN BEGIN
- report := True;
- IF code<>status THEN BEGIN
- status := code;
- IF (status SHR 8)>I2C_NO_REPLY THEN BEGIN
- WriteLn(fenster,'I²C bus: error $',hexstr(status,6),', ',I2CErrText(status));
- IF Ptr(GetI2COpponent)<>Nil THEN
- WriteLn(fenster,'"',GetI2COpponent,'" has got our hardware');
- END;
- END;
- END ELSE
- report := False;
- END;
- BEGIN
- Page(fenster);
- WriteLn(fenster);
- WriteLn(fenster,'Scanning for listeners ...');
- WriteLn(fenster);
- wr := False; rd := False; status := 0;
- FOR i := 0 TO 127 DO BEGIN
- wr := NOT report(SendI2C(2*i,0,^buffer));
- rd := NOT report(ReceiveI2C(2*i+1,1,^buffer));
- IF rd OR wr THEN BEGIN
- Write(fenster,'Chip address $');
- IF rd AND wr THEN BEGIN
- Write(fenster,hexstr(2*i,2),'/$');
- Write(fenster,hexstr(2*i+1,2),': R/W');
- END ELSE IF rd THEN
- Write(fenster,hexstr(2*i+1,2),': R only')
- ELSE
- Write(fenster,hexstr(2*i,2),': W only');
- IF verbose THEN BEGIN
- identify(2*i);
- Write(fenster,'Press any key: ');
- Read(fenster,ch);
- IF ch=#27 THEN Exit;
- Write(fenster,#13' ');
- END;
- WriteLn(fenster);
- END;
- IF WaitForChar(FileHandle(fenster),0) THEN Exit;
- END;
- Write(fenster,'Scan complete. ');
- Read(fenster,ch);
- END;
-
- BEGIN
- OpenLib(I2CBase,'i2c.library',39);
- Reset(fenster,'RAW:20/60/600/120/I2CScan, ESC to quit');
- busdelay := SetI2CDelay(I2CDELAY_READONLY);
- locked := False;
- allocresult := 0; { stimmt zwar nicht ... }
- REPEAT
- IF SetI2CDelay(busdelay)=busdelay THEN { :-) };
- Page(fenster);
- WriteLn(fenster);
- IF locked THEN Write(fenster,#155'7m');
- WriteLn(fenster,'L(ock'#155'0m S(can I(dentify');
- Write(fenster,'+-/*: Set I²C delay (',busdelay,') ');
- Read(fenster,ch);
- WriteLn(fenster,ch);
- CASE ch OF
- '+': Inc(busdelay);
- '-': Dec(busdelay);
- '*': busdelay := busdelay SHL 1;
- '/': busdelay := busdelay SHR 1;
- 's','S': scan(False);
- 'i','I': scan(True);
- 'l','L': BEGIN locked := NOT locked;
- IF locked THEN ShutDownI2C ELSE allocresult := BringBackI2C;
- END;
- OTHERWISE;
- END;
- IF busdelay<0 THEN busdelay := 0;
- UNTIL ch=#27;
- Close(fenster);
- CloseLib(I2CBase);
- END.
-
-