home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / VIDEOTEXT.LZX / VTsrc / i2cscan.p < prev    next >
Encoding:
Text File  |  1996-02-28  |  5.1 KB  |  150 lines

  1. PROGRAM i2cscan;
  2. { Schaut, wer am I²C-Bus angeschlossen ist und zuhört. }
  3. {$incl "i2c.lib" }
  4.  
  5. VAR busdelay: Long;
  6.     locked: Boolean;
  7.     allocresult: Byte;
  8.     ch: Char;
  9.     fenster: Text;
  10.  
  11. FUNCTION hexstr(l: Long; digits: Integer): Str;
  12. { Zahl mit mindestens <digits> Stellen nach Hex wandeln: }
  13. VAR i,j,x: Integer;
  14.     s: String[10]; STATIC; { Wichtig! }
  15. BEGIN
  16.   IF digits<1 THEN digits := 1;
  17.   j := 1;
  18.   FOR i := 7 DOWNTO 0 DO
  19.     IF (i<digits) OR (l SHR (4*i)>0) THEN BEGIN
  20.       x := (l SHR (4*i)) AND $F;
  21.       IF x<10 THEN s[j] := Chr(x+ord('0'))
  22.       ELSE s[j] := Chr(x-10+ord('A'));
  23.       Inc(j);
  24.     END;
  25.   s[j] := #0;
  26.   hexstr := ^s;
  27. END;
  28.  
  29. PROCEDURE identify(adr: Byte);
  30. { Nicht besonders aussagekräftig: die meisten Chips lassen sich auf -zig }
  31. { verschiedene Adressen einstellen, haben diese dann aber mit mehreren }
  32. { anderen gemeinsam. }
  33. BEGIN
  34.   WriteLn(fenster,', might be:');
  35.   IF adr = $20 THEN WriteLn(fenster,'PCF8200: speech synthesizer');
  36.   IF adr = $22 THEN WriteLn(fenster,'SAA5243/SAA5246: teletext decoder');
  37.   IF adr IN [$20,$22] THEN WriteLn(fenster,'SAF1135/SAA4700: VPS decoder');
  38.   IF adr IN [$40..$4E] THEN WriteLn(fenster,'PCF8574: 8 bit IO expander');
  39.   IF adr IN [$70..$7E] THEN WriteLn(fenster,'PCF8574A: 8 bit IO expander');
  40.   IF adr IN [$90..$9E] THEN WriteLn(fenster,'PCF8591: 8 bit DA/AD converter');
  41.   IF adr IN [$70..$76] THEN WriteLn(fenster,'SAA1064: LED driver 2-4 × 8');
  42.   IF adr IN [$70,$72] THEN WriteLn(fenster,'PCF8576: LCD driver 1-4 × 40');
  43.   IF adr = $74 THEN WriteLn(fenster,'PCF8577: LCD driver 1-2 × 32');
  44.   IF adr = $76 THEN WriteLn(fenster,'PCF8577A: LCD driver 1-2 × 32');
  45.   IF adr IN [$7C,$7E] THEN WriteLn(fenster,'PCF8566: LCD driver 1-4 × 24');
  46.   IF adr IN [$78,$7A] THEN BEGIN
  47.     WriteLn(fenster,'PCF8578: LCD dot matrix driver 32×8, 24×16, 16×24 or 8×32,');
  48.     WriteLn(fenster,'    possibly with one or more PCF8579 (40 extra columns)');
  49.   END;
  50.   IF adr IN [$A0..$AE] THEN WriteLn(fenster,'PCF8570/PCF8571: 256/128 byte SRAM');
  51.   IF adr IN [$A0..$AE] THEN WriteLn(fenster,'PCF8581/PCF8582: 256/128 byte EEPROM');
  52.   IF adr IN [$B0..$BE] THEN WriteLn(fenster,'PCF8570C: 256 byte SRAM');
  53.   IF adr IN [$D0..$D6] THEN WriteLn(fenster,'PCF8573: clock/calendar');
  54.   IF adr IN [$A0,$A2] THEN WriteLn(fenster,'PCF8583: clock/calendar and 256 byte SRAM');
  55.   IF adr IN [$80..$86] THEN WriteLn(fenster,'SAA1300: power output 5×85 mA');
  56.   IF adr = $88 THEN WriteLn(fenster,'TDA8442: DAC & switch for color decoder');
  57.   IF adr IN [$90..$9E] THEN WriteLn(fenster,'TDA8440: AV input selector');
  58.   IF adr IN [$40..$4E] THEN WriteLn(fenster,'TDA8444: 8 × 6 bit D/A converter');
  59. END;
  60.  
  61. PROCEDURE scan(verbose: Boolean);
  62. VAR rd,wr: Boolean;
  63.     status: Long;
  64.     i,buffer: Integer;
  65. LIBRARY DosBase:
  66. -204: FUNCTION WaitForChar(D1: Long; D2: Long): Boolean;
  67. END;
  68. FUNCTION report(code: Long): Boolean;
  69. { Fehlermeldung ausgeben, True, wenn wirklicher Fehler }
  70. BEGIN
  71.   IF (code AND $FF)=0 THEN BEGIN
  72.     report := True;
  73.     IF code<>status THEN BEGIN
  74.       status := code;
  75.       IF (status SHR 8)>I2C_NO_REPLY THEN BEGIN
  76.         WriteLn(fenster,'I²C bus: error $',hexstr(status,6),', ',I2CErrText(status));
  77.         IF Ptr(GetI2COpponent)<>Nil THEN
  78.           WriteLn(fenster,'"',GetI2COpponent,'" has got our hardware');
  79.       END;
  80.     END;
  81.   END ELSE
  82.     report := False;
  83. END;
  84. BEGIN
  85.   Page(fenster);
  86.   WriteLn(fenster);
  87.   WriteLn(fenster,'Scanning for listeners ...');
  88.   WriteLn(fenster);
  89.   wr := False; rd := False; status := 0;
  90.   FOR i := 0 TO 127 DO BEGIN
  91.     wr := NOT report(SendI2C(2*i,0,^buffer));
  92.     rd := NOT report(ReceiveI2C(2*i+1,1,^buffer));
  93.     IF rd OR wr THEN BEGIN
  94.       Write(fenster,'Chip address $');
  95.       IF rd AND wr THEN BEGIN
  96.         Write(fenster,hexstr(2*i,2),'/$');
  97.         Write(fenster,hexstr(2*i+1,2),': R/W');
  98.       END ELSE IF rd THEN
  99.         Write(fenster,hexstr(2*i+1,2),': R only')
  100.       ELSE
  101.         Write(fenster,hexstr(2*i,2),': W only');
  102.       IF verbose THEN BEGIN
  103.         identify(2*i);
  104.         Write(fenster,'Press any key: ');
  105.         Read(fenster,ch);
  106.         IF ch=#27 THEN Exit;
  107.         Write(fenster,#13'              ');
  108.       END;
  109.       WriteLn(fenster);
  110.     END;
  111.     IF WaitForChar(FileHandle(fenster),0) THEN Exit;
  112.   END;
  113.   Write(fenster,'Scan complete. ');
  114.   Read(fenster,ch);
  115. END;
  116.  
  117. BEGIN
  118.   OpenLib(I2CBase,'i2c.library',39);
  119.   Reset(fenster,'RAW:20/60/600/120/I2CScan, ESC to quit');
  120.   busdelay := SetI2CDelay(I2CDELAY_READONLY);
  121.   locked := False;
  122.   allocresult := 0; { stimmt zwar nicht ... }
  123.   REPEAT
  124.     IF SetI2CDelay(busdelay)=busdelay THEN { :-) };
  125.     Page(fenster);
  126.     WriteLn(fenster);
  127.     IF locked THEN Write(fenster,#155'7m');
  128.     WriteLn(fenster,'L(ock'#155'0m  S(can  I(dentify');
  129.     Write(fenster,'+-/*: Set I²C delay (',busdelay,') ');
  130.     Read(fenster,ch);
  131.     WriteLn(fenster,ch);
  132.     CASE ch OF
  133.       '+': Inc(busdelay);
  134.       '-': Dec(busdelay);
  135.       '*': busdelay := busdelay SHL 1;
  136.       '/': busdelay := busdelay SHR 1;
  137.       's','S': scan(False);
  138.       'i','I': scan(True);
  139.       'l','L': BEGIN locked := NOT locked;
  140.           IF locked THEN ShutDownI2C ELSE allocresult := BringBackI2C;
  141.         END;
  142.       OTHERWISE;
  143.     END;
  144.     IF busdelay<0 THEN busdelay := 0;
  145.   UNTIL ch=#27;
  146.   Close(fenster);
  147.   CloseLib(I2CBase);
  148. END.
  149.  
  150.