Re: Colarado Spectrum Workstation Gameport

New Message Reply Date view Thread view Subject view Author view

Simon Bennett (simonb++at++wormald.com.au)
Thu, 12 Jun 1997 12:15:03 +1010 (EST)


On Wed, 11 Jun 1997, Nigel Jenkins wrote:

> 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/


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:55:25 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.