Raw Joystick Access


amunra

Still Fresh
Joined
Jun 19, 2010
Messages
3
Hi all,

I am currently porting an existing Linux application, so far everything seems to work well, X11, ALSA etc... I have one problem, I can't seem to access the nubs as joystick devices... I can see /dev/input/js0 and /dev/input/js1 exist, and open but I dont get any data. I have found that I need to switch the joysticks into absolute mode first, yet its not producing any data. Here are the two main functions I am using to access the hardware, any help would be very welcome...

Code:
int open_joystick( INT_S16 stick_number )
{
        int fd;
        FILE *f;
        INT_S8 buffer[50];

        // make sure nub is in game mode
        sprintf( buffer, "/proc/pandora/nub%d/mode", stick_number-1 );
        f = fopen( buffer, "w+" );
        if( f )
        {
                // make the request
                fputs( "absolute", f );
                fclose( f );
        }

        // try to open this file
        sprintf( buffer, "/dev/input/js%d", stick_number-1 );
        fd = open( buffer, O_RDONLY|O_NONBLOCK );

        // did it open?
        return fd;
}

IBOOL JOYSTICK::read_joystick( void )
{
        int fd=-1;
        struct js_event event;

        <<snip, fd set to result of open_joystick()>>

        // loop through events (when no events left -1 returned and errno==EAGAIN)
        while( read( fd, &event, sizeof(event) ) > 0 )
        {
                // button changed?
                if( (event.type & ~JS_EVENT_INIT) == JS_EVENT_BUTTON )
                {
                        // set button flag
                        if( event.value )
                                button_flags |= (1 << event.number);
                        else
                                button_flags &= ~(1 << event.number);
                }

                // button changed?
                if( (event.type & ~JS_EVENT_INIT) == JS_EVENT_AXIS )
                {
                        // set axis
                        switch( event.number )
                        {
                                case 0: x = event.value; break;
                                case 1: y = event.value; break;
                                case 2: z = event.value; break;
                                case 3: axis_4 = event.value; break;
                                case 4: axis_5 = event.value; break;
                                case 5: axis_6 = event.value; break;
                        }
                }
        }

        // clear down pov
        pov_angle = 0;

        // all done
        return TRUE;

} // read_joystick()
 
Follow this:

http://pandorawiki.org/Kernel_interface

nub0 and nub1 will appear as two devices under /dev/input/eventX. Otherwise should integrate fairly cleanly into the existing event loop.
 
Libpnd includes pnd-io-evdev conveniance API which works great. But for gettin it to work as standard js .. Should work too if set to joystick mode perhaps? I forget offhand but sdl will detect them as joysticks just fine. Each nub is separate joystick

jeff
 
Exophase said:
Follow this:

http://pandorawiki.org/Kernel_interface

nub0 and nub1 will appear as two devices under /dev/input/eventX. Otherwise should integrate fairly cleanly into the existing event loop.
Thanks a lot, that page has a lot of useful info that allowed me to fix my issue. I now have raw nub data. Oh and great little device, I really am enjoying hacking it...
 
Last edited by a moderator:
Near a PC for a few minutes; the libpnd bit I mentined is here:

http://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-libraries.git;a=blob;f=lib/pnd_io_evdev.c;h=98a85507bce682f406a3347a55d5f82f10df4263;hb=75575c6109c5ceecd99dd38e815feefcc1becb6c

jeff
 
torpor said:
please share the fix!
Nothing ground breaking, I just followed the example in the link posted. I had to use the /dev/input/eventX device files rather than the /dev/js0 ones. It says in the doc to scan the event files as they may change in the future. Here is my code to find and open the joysticks:

Code:
	// keep looping
	sprintf( name, "nub%d", stick_number-1 );
	for( i=0; TRUE; i++ )
	{
		// open this event file
		sprintf( buffer, "/dev/input/event%i", i );
    		fd = open( buffer, O_RDONLY|O_NONBLOCK );
		if( fd < 0 ) break;

		// get the device name
		ioctl( fd, EVIOCGNAME(sizeof(buffer)), buffer );
	  	if( strcmp( buffer, name ) == 0 )
  			return fd;
	    	close(fd);
	}

	// no stick found
	return -1;

Then I had to re-write the joystick event code as it works slightly differently to the std Linux joystick interface. Here is a code snippet that reads the joystick values:

Code:
	// loop through events (when no events left -1 returned)
	while( read( fd, &event, sizeof(event) ) > 0 )
	{
		// joystick changed?
		if( event.type == EV_ABS )
		{
			// set axis
			switch( event.code )
			{
				case ABS_X: x = event.value; break;
				case ABS_Y: y = event.value; break;
			}
		}
	}
 
Last edited by a moderator:
Back
Top