port 0 und 1 als Eingabe, Port 2 und 3 als Ausgabe

Dies ist das deutsche Forum für alle Themen um den IO-Warrior. Beiträge bitte nur in Deutsch.

Moderator: Guido Körber

Post Reply
l_netwalker
Posts: 35
Joined: Mon Oct 17, 2005 9:51 am
Location: Aachen, Germany
Contact:

port 0 und 1 als Eingabe, Port 2 und 3 als Ausgabe

Post by l_netwalker »

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
Guido Körber
Site Admin
Posts: 2876
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Post by Guido Körber »

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.
l_netwalker
Posts: 35
Joined: Mon Oct 17, 2005 9:51 am
Location: Aachen, Germany
Contact:

Post by l_netwalker »

Hallo,

mein Problem ist, dass ein read der ports meinen zuvor geschriebenen
Wert überschreibt. Meine Steuerung macht im wesentlichen:

loop
read
berechne ergebnis
schreibe
pause
endloop

ich kann an Hand von debuggingausgaben sehen, dass der read
die Ausgänge auf 1 setzt.

was mach ich da falsch ?
l_netwalker
Posts: 35
Joined: Mon Oct 17, 2005 9:51 am
Location: Aachen, Germany
Contact:

Post by l_netwalker »

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
Robert Marquardt
Posts: 543
Joined: Mon Dec 01, 2003 6:09 pm

Post by Robert Marquardt »

Die CODE Tags nicht vergessen.
supachris
Posts: 124
Joined: Tue Mar 16, 2004 12:30 am
Location: Dresden

Post by supachris »

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.
Gruß SupaChris
l_netwalker
Posts: 35
Joined: Mon Oct 17, 2005 9:51 am
Location: Aachen, Germany
Contact:

Post by l_netwalker »

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

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.
l_netwalker
Posts: 35
Joined: Mon Oct 17, 2005 9:51 am
Location: Aachen, Germany
Contact:

Post by l_netwalker »

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 :lol:
Allerdings so gründlich, dass ich den Fehler einfach nicht finde :cry:
Wer kann mir helfen ?

Gruss Hartmut
Post Reply