Simon Bennett (simonb++at++wormald.com.au)
Thu, 12 Jun 1997 12:15:03 +1010 (EST)
> Hi,
> Does anyone have any experience of using a Colarado Spectrum Workstation
> Gameport with any SG Hardware (especially an Onyx IR or Indigo2). I
> wish to attach a Microsoft Sidewinder joystick to our Onyx for some user
> centred walk-throughs.
> The Workstation Gameport appears to be the right equipment for the job,
> but I can't find much information on the the hardware or the supplier.
> If anyone has any information, especially technical documentation or
> example code, code they please get in touch.
> Thanks
Colorado Spectrum's details are:
Colorado Spectrum
1001-A East Harmony Road, #501
Fort Collins, CO 80525
Phone: (800) 238-5983 or (970) 225-6929
FAX: (970) 225-1663
Blurb:
The WG is very similar to the Notebook Gameport except that it uses standard
serial protocols instead of a proprietary protocol. ( The NG uses the Ring and
DCD lines to bring in data synchronously so that the standard Txd and Rxd lines
are free to be used in the pass-through port. To avoid the difficult (in Unix)
"real-time" task of reading in data bit by bit, the WG makes use of the serial
port's UART and the standard Rxd line and as such does not support a
pass-through serial port.)
The WG is a very small card that is able to measure the resistance of 2 analog PC-like
Joystick, plus the state of 4 buttons (located on the same joystick or not). It is actally a
workstation version of a PC dual-joystick port. The WG sends in a 6-byte 9600 (N, 8,
2) baud data packet whenever a stick is moved or a button is pressed or released.
Writing a driver for the WG is therefore very similar to a simple serial mouse driver.
Colorado Spectrum has sold WG's to Sun, SGI, HP, DEC, etc. customers already but
do not have a "generic" driver available so one would need to create their own. This
however will be an order of magnitude easier than writing a real-time driver for the
NG (which they do not release the protocol for anyway).
One can connect any PC joystick without doing any special wiring.
If one wants to use 2 different joysticks. One would just have to make a cable
that directs the good potentiometers values and switches to the good connections onto
the WG.
I also have this:
(I believe the originator is a guy called David Nahon, you could try
nahond++at++ccr.jussieu.fr if you need more info)
Wiring to SGI's. You'll have to modify this for an Onyx2 or an O2.
/*
DB Male WG DIN8 Male(Indigo/Indy) Name
-----1---------------------7-----------------DCD
-----2---------------------5-----------------RD
-----3---------------------3-----------------TD
-----4---------------------1-----------------DTR
-----5---------------------8-----------------SG
-----7---------------------6-----------------RTS
-----8---------------------2-----------------CTS
DB Male WG DB9 Male (Onyx) Name
-----1----------------------8---------------DCD
-----2----------------------3---------------RD
-----3----------------------2---------------TD
-----4----------------------9---------------DTR
-----5----------------------7---------------SG
-----7----------------------4---------------RTS
-----8----------------------5---------------CTS
*/
Then you need to power the device, and that can be done directly from the DTR
and RTS signals that have to remain high.
Some sample source:
/*
* Minimal Demo for using Colorado Spectrum Workstation Gameport
*/
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <stdio.h>
extern int sginap (long ticks);
typedef struct _WG_State {
int buttons;
int joy1_pot1;
int joy1_pot2;
int joy2_pot1;
int joy2_pot2;
} WG_State ;
#define READBLOCK 0
#define READNONBLOCK 1
#define JOY_BUT_1 1
#define JOY_BUT_2 2
#define JOY_BUT_3 4
#define JOY_BUT_4 8
#define JOY1_POT1 1
#define JOY1_POT2 2
#define JOY2_POT1 3
#define JOY2_POT2 4
char values[6]={0, 0, 0, 0, 0, 0};
int joyfd;
/******************************************************************
*
*/
void get_joystick(WG_State* wgs)
{
int n;
char byte0;
/* wait for sync byte that is always 0*/
do
{
n=read(joyfd, &byte0, 1);
/* printf("%d %c\n", n, byte0); */
if (n==-1)
{
fprintf(stderr, "Error reading joy fd\n");
return;
}
}
while((byte0!=0));
n=read(joyfd, values, 5);
if (n==-1)
{
fprintf(stderr, "Error reading joy fd\n");
return;
}
wgs->buttons = (values[0] - 0xf) >> 4;
wgs->joy1_pot1 = (int)values[JOY1_POT1];
wgs->joy1_pot2 = (int)values[JOY1_POT2];
wgs->joy2_pot1 = (int)values[JOY2_POT1];
wgs->joy2_pot2 = (int)values[JOY2_POT2];
}
void get_joystick_NON_BLOCK(WG_State* wgs)
{
int n;
char byte0;
/* wait for sync byte that is always 0*/
do
{
n=read(joyfd, &byte0, 1);
/* printf("%d %c\n", n, byte0); */
if (n==-1)
return;
}
while( (n!=1) || (byte0!=0) );
n=read(joyfd, values, 5);
if (n==-1)
return;
wgs->buttons = (values[0] - 0xf) >> 4;
wgs->joy1_pot1 = (int)values[JOY1_POT1];
wgs->joy1_pot2 = (int)values[JOY1_POT2];
wgs->joy2_pot1 = (int)values[JOY2_POT1];
wgs->joy2_pot2 = (int)values[JOY2_POT2];
}
void init_joystick( int portnum, int nonblock )
{
int result;
int flags=TIOCM_DTR|TIOCM_RTS|TIOCM_LE|TIOCM_CTS;
char str232[128];
struct termio termio;
printf("----------------------------------------------------------------\n");
printf("Initialisation du Joystick...\n");
sprintf( str232, "/dev/ttyd%d", portnum );
printf("Use RS232-Device %s for Workstation GamePort JOYSTICK\n", str232 );
joyfd = open( str232, O_RDONLY);
if ( joyfd == -1 )
{
printf( "Can't open seriel port /dev/ttyd%d\n", portnum );
exit(1);
}
result = ioctl( joyfd, TCGETA, &termio );
if (nonblock)
fcntl(joyfd, F_SETFL, FNONBLK);
termio.c_iflag = 0;/*IXON|IXOFF|IGNBRK | IGNPAR;*/
termio.c_oflag = 0;
termio.c_cflag = B9600 | CS8 | CREAD | CLOCAL| CSTOPB;
termio.c_lflag = 0; /* -ECHO */
ioctl( joyfd, TCSETA, &termio );
/*
* check if gameport is likelly to be properly powered,
* i.e TIOCM_RTS and TIOCM_DTR must be high
*/
ioctl( joyfd, TIOCMGET,&flags );
if ( (flags&(TIOCM_RTS|TIOCM_DTR)) != (TIOCM_RTS|TIOCM_DTR) )
{
fprintf(stderr, "------> TIOCM_RTS and TIOCM_DTR not 1\n");
printf("TIOCM_RTS(%d) et TIOCM_DTR(%d) /
(TIOCMGET=%x)\n",TIOCM_RTS,TIOCM_DTR, flags);
exit(1);
}
printf("Init done.\n");
printf("----------------------------------------------------------------\n");
}
void print_wgstate(const WG_State* wgs)
{
printf("J1_POT1:%3d ", wgs->joy1_pot1 );
printf("J1_POT2:%3d ", wgs->joy1_pot2 );
printf("J2_POT1:%3d ", wgs->joy2_pot1 );
printf("J2_POT2:%3d ", wgs->joy2_pot2 );
if ( wgs->buttons & JOY_BUT_1)
printf("BUT_1 ");
else
printf(" ");
if ( wgs->buttons & JOY_BUT_2)
printf("BUT_2 ");
else
printf(" ");
if ( wgs->buttons & JOY_BUT_3)
printf("BUT_3 ");
else
printf(" ");
if ( wgs->buttons & JOY_BUT_4)
printf("BUT_4 ");
else
printf(" ");
/* printf("\r"); */
printf("\n");
fflush(stdout);
}
void close_joystick()
{
close( joyfd );
}
main(int argc, char **argv)
{
WG_State wg_state;
int nonblock=0;
int portnumber=-1;
if( (argc!=2) && (argc!=3) )
{
printf("Usage: %s <serial_number> [nb]\n If nb is used, the serial-line read
won't block\n", argv[0]);
exit(1);
}
portnumber=atoi(argv[1]);
if (!portnumber)
{
fprintf(stderr, "Bad port number\n");
exit(1);
}
if ( (argc==3) && (strcmp(argv[2], "nb")) == 0 ) /* non blocking mode */
{
init_joystick( portnumber, READNONBLOCK );
while(1)
{
get_joystick_NON_BLOCK(&wg_state);
print_wgstate(&wg_state);
sginap(1);
}
}
else
{
init_joystick( portnumber, READBLOCK );
while(1)
{
get_joystick(&wg_state);
print_wgstate(&wg_state);
}
}
}
One can connect any PC joystick without doing any special wiring, I've used a Gravis,
which has 4 independant buttons.
If one wants to use 2 different joysticks, I guess you just have to make a cable that
directs the good potentiometers values and switches to the good connections onto the
WG, knowing that the joystick DB-15 connector on the WG has the following pinout:
Pin Number Function
1,8,9,15 +5V (Pot common)
2 Switch 1
3 Pot 1
4,5,12 Ground (Switch common)
6 Pot 2
7 Sw 2
10 Sw 3
11 Pot 3
13 Pot 4
14 Sw 4
+----------------------------------------------------------------------------+
Simon Bennett simonb++at++wormald.com.au
Wormald Technology Advanced Systems Engineering Ph: +61 2 9981 0669
"Good judgement is the result of experience.
Experience is the result of poor judgement"
=======================================================================
List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/
Submissions: info-performer++at++sgi.com
Admin. requests: info-performer-request++at++sgi.com
SGI DevForum 97 info: http://www.sgi.com/Forum97/
This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:55:25 PDT