Hallo,
ich versuche eine Anwendung die bisher eine 8255 PIO benutzt hat auf den IO Warrior umzustricken. Ist es möglich, wie im Subject genannt,
die beiden unteren Ports zu lesen und die beiden oberen zu schreiben ?
oder muss ich da mit 2 Warrior 40 machen, einen zum lesen den anderen zum schreiben ?
Vielen Dank
Hartmut
port 0 und 1 als Eingabe, Port 2 und 3 als Ausgabe
Moderator: Guido Körber
-
- Posts: 35
- Joined: Mon Oct 17, 2005 9:51 am
- Location: Aachen, Germany
- Contact:
-
- Site Admin
- Posts: 2876
- Joined: Tue Nov 25, 2003 10:25 pm
- Location: Germany/Berlin
- Contact:
Also alle Pins liefern generell den Status am Pin zurück, funktionieren also ständig als Input. Damit das richtig geht muss der Pin natürlich auf 1 geschrieben werden, damit nur der interne Pull-Up aktiv ist und nicht der Open Drain Treiber.
Also die Pins die als Eingänge laufen sollen immer auf 1 setzen.
Also die Pins die als Eingänge laufen sollen immer auf 1 setzen.
-
- Posts: 35
- Joined: Mon Oct 17, 2005 9:51 am
- Location: Aachen, Germany
- Contact:
-
- Posts: 35
- Joined: Mon Oct 17, 2005 9:51 am
- Location: Aachen, Germany
- Contact:
Ist es eigentlich ok hier auch Ceode zu posten ?
Da meine Anwendung vom 8255 her kommt ist der ganze IO Zugriff
natuerlich port orientiert. Daher mache ich an der Stelle auch heftige Verrenkungen die natürlich auch Quelle meines Problems sein können.
Wenns ok ist würd ich die knapp 200 Zeilen mal posten. Vielleicht seht Ihr ja auch was ich falsch mache.
Gruss
Hartmut
Da meine Anwendung vom 8255 her kommt ist der ganze IO Zugriff
natuerlich port orientiert. Daher mache ich an der Stelle auch heftige Verrenkungen die natürlich auch Quelle meines Problems sein können.
Wenns ok ist würd ich die knapp 200 Zeilen mal posten. Vielleicht seht Ihr ja auch was ich falsch mache.
Gruss
Hartmut
Naja, portweise Lesen oder Schreiben geht beim IOW nicht. Es weden immer alle Ports insgesamt gelesen oder geschrieben. Aber ein Lesen sollte an den Portzuständen nix ändern, da hast du dort nen Fehler drin.
Portweise lesen ist ja recht einfach zu machen: gesamte 32 Bit (beim IOW40) auslesen und durch schieben und maskieren die 4 mal 8 Bit raussuchen.
Portweise schreiben ist bissl auswendger, dazu musst du zuerst den Portzustand lesen, zwischenspeichern, den neuen Portwert an die passende Stelle rotieren und mit dem alten Wert Oder-Verknüpfen. Und wenn ein Port Eingang sein soll, an der richtigen Stelle im DWORD halt alles 1en schreiben.
Portweise lesen ist ja recht einfach zu machen: gesamte 32 Bit (beim IOW40) auslesen und durch schieben und maskieren die 4 mal 8 Bit raussuchen.
Portweise schreiben ist bissl auswendger, dazu musst du zuerst den Portzustand lesen, zwischenspeichern, den neuen Portwert an die passende Stelle rotieren und mit dem alten Wert Oder-Verknüpfen. Und wenn ein Port Eingang sein soll, an der richtigen Stelle im DWORD halt alles 1en schreiben.
Gruß SupaChris
-
- Posts: 35
- Joined: Mon Oct 17, 2005 9:51 am
- Location: Aachen, Germany
- Contact:
Hallo,
im Prinzip mache ich das was supachris vorschlägt. Hier mein Code einer Unit in FreePascal für den IO-Warrior 40.
ich meine daß das eigentlich so funktionieren sollte.
Vielen Dank für Eure Hilfe
Hartmut
im Prinzip mache ich das was supachris vorschlägt. Hier mein Code einer Unit in FreePascal für den IO-Warrior 40.
ich meine daß das eigentlich so funktionieren sollte.
Vielen Dank für Eure Hilfe
Hartmut
Code: Select all
Unit iow_io_access;
{ diese Unit stellt Funktionen zum I/O Access auf }
{ die Ports des IO Warriors 40 von Code Mercanaries zur Verfügung }
{ If you have improvements please contact me at }
{ hartmut@eilers.net }
{ all code is copyright by Hartmut Eilers and released under }
{ the GNU GPL see www.gnu.org for license details }
{ History: }
{ 10.09.2005 first raw hack }
{ 22.09.2005 able to read selected ports }
INTERFACE
{ the io_port address has a special meaning: its a two digit number with the first digit }
{ addressing the io warrior device ( eg. /dev/usb/iowarrior1 [ range 0-3 ]) and the second digit meaning }
{ which of the four eight bit ports should be read ( range 0-3 ) }
{ address 13 read the second iowarrior and returns the value of port 3 }
{ the ranges are not checked ! }
function read_ports(io_port:longint):byte;
function write_ports(io_port:longint;byte_value:byte):byte;
function hwinit(initdata:string):boolean;
implementation
uses oldlinux;
const
(* These values are from the SDK Sample program iow40_wr_if0.c *)
(* IOW_WRITE=1074053121 *)
(* IOW_READ =1074053122 *)
(* This must be improved, it's bad style to use the constants *)
IOW_WRITE = 1074053121;
IOW_READ = 1074053122;
war_max = 4; { max number of iowarriors which are supported }
debug = true;
devicefile= '/dev/usb/iowarrior';
var
f : LongInt;
pvalue : ^Cardinal;
oldval : array[1..war_max] of Cardinal;
function read_ports(io_port:longint):byte;
var
ivalue : Cardinal;
devicenr,
device : string;
begin
{ extract the device number and build devicename }
str(round(io_port/10),devicenr);
device:=devicefile+devicenr;
{ extract the port }
io_port:=round(frac(io_port/10)*10);
(* read the warrior *)
f:=fdOpen(device,Open_RdOnly);
ioctl (f,IOW_READ,pvalue);
fdclose(f);
ivalue:=pvalue^;
if ( debug ) then writeln ('IOW_IO: r ',device,' ',io_port,':',ivalue);
{ return the wanted port }
case io_port of
0 : read_ports:=ivalue;
1 : read_ports:=ivalue shr 8;
2 : read_ports:=ivalue shr 16;
3 : read_ports:=ivalue shr 24;
end;
end;
function write_ports(io_port:longint;byte_value:byte):byte;
{ in this dirty hack the port parameter is not fully implemented! }
var
ovalue : Cardinal;
devicenr,
device : string;
dev : LongInt;
begin
{ extract the device number and build devicename }
dev:=round(io_port/10);
str(dev,devicenr);
device:=devicefile+devicenr;
{ extract the port }
io_port:=round(frac(io_port/10)*10);
(* write the warrior *)
{ shift the outvalue to the Port }
write ('ovalue0=',byte_value,' ');
case io_port of
0 : begin
ovalue:=(byte_value ) or $FFFFFF00;
oldval[dev+1]:=oldval[dev+1] and $FFFFFF00;
end;
1 : begin
ovalue:=(byte_value shl 8) or $FFFF00FF;
oldval[dev+1]:=oldval[dev+1] and $FFFF00FF;
end;
2 : begin
ovalue:=(byte_value shl 16) or $FF00FFFF;
oldval[dev+1]:=oldval[dev+1] and $FF00FFFF;
end;
3 : begin
ovalue:=(byte_value shl 24) or $00FFFFFF;
oldval[dev+1]:=oldval[dev+1] and $00FFFFFF;
end;
end;
write ('ovalue1=',ovalue,' oldval=',oldval[dev+1],' ');
{ the values of the other ports must be brought into ovalue }
ovalue:=oldval[dev+1] or ovalue;
writeln ('ovalue2=',ovalue,' ');
{ note the new value written to the warrior for next port access }
oldval[dev+1]:=oldval[dev+1] or ovalue;
if (debug) then writeln ('IOW_IO: w ',device,' ',dev,' ', io_port,':',ovalue);
{ write out }
pvalue^:=ovalue;
f:=fdOpen(device,Open_WrOnly);
ioctl (f,IOW_WRITE,pvalue);
fdclose(f);
end;
function hwinit(initdata:string):boolean;
var
x : byte;
begin
if (debug) then writeln ( 'IOW_IO: IO-Warrior initilized' );
for x:=1 to war_max do
oldval[x]:=0;
end;
begin
new (pvalue);
end.
-
- Posts: 35
- Joined: Mon Oct 17, 2005 9:51 am
- Location: Aachen, Germany
- Contact:
Hallo,
Ich konnte meinen Fehler inzwischen besser einkreisen.
Es ist nicht wie vermutet der read access der meinen Port
zurücksetzt, sondern der write der die Daten für port 3 setzen soll.
der Fehler liegt in write_ports.
Da hab ich mich wohl beim "and/or'en" verboolscht
Allerdings so gründlich, dass ich den Fehler einfach nicht finde
Wer kann mir helfen ?
Gruss Hartmut
Ich konnte meinen Fehler inzwischen besser einkreisen.
Es ist nicht wie vermutet der read access der meinen Port
zurücksetzt, sondern der write der die Daten für port 3 setzen soll.
der Fehler liegt in write_ports.
Da hab ich mich wohl beim "and/or'en" verboolscht

Allerdings so gründlich, dass ich den Fehler einfach nicht finde

Wer kann mir helfen ?
Gruss Hartmut