#include <unistd.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/joystick.h> #include <stdio.h> #include <stdlib.h> void print_data(int aval[], int bval[], int axes, int btns) { int i; for (i=0; i<btns; i++) { printf("%2d |", bval[i]); } for (i=0; i<axes; i++) { printf(" %5d |", aval[i]); } printf(" \r"); fflush(stdout); } void print_data_hdr(int aval[], int bval[], int axes, int btns) { int i; printf("js0: axes=%d, buttons=%d\n", axes, btns); for (i=0; i<btns; i++) { printf("b%02d|", i); } for (i=0; i<axes; i++) { printf(" a%02d |", i, aval[i]); } printf("\n"); for (i=0; i<btns; i++) { printf("____"); } for (i=0; i<axes; i++) { printf("________"); } printf("\n"); } int main(int argc, char *argv[]) { int fd,i; int aval[256]; int bval[256]; int min[256]; int max[256]; int dmin[256]; int dmax[256]; int count=0; int nobutton=0; unsigned char axes, btns; struct js_event ev; struct js_corr cor[64]; if (argc>=2) fd=open(argv[1], O_RDONLY|O_NONBLOCK); else fd=open("/dev/input/js0", O_RDONLY|O_NONBLOCK); if (fd<0) { perror("Failed to open device"); return 1; } ioctl(fd, JSIOCGAXES, &axes); ioctl(fd, JSIOCGBUTTONS, &btns); for (i=0; i<64; i++) { cor[i].type=JS_CORR_NONE; cor[i].coef[0]=128; cor[i].coef[1]=128; cor[i].coef[2]=65536*64; cor[i].coef[3]=65536*64; } ioctl(fd, JSIOCSCORR, cor); printf("Leave all axes centred, press a button when ready\n"); print_data_hdr(aval, bval, axes, btns); for (i=0; i<axes; i++) aval[i]=128; for (i=0; i<axes; i++) bval[i]=0; //get initial values; nobutton=0; while (nobutton==0) { while (read(fd, &ev, sizeof(ev))==sizeof(ev)) { if (ev.type&JS_EVENT_BUTTON) bval[ev.number]=ev.value; if (ev.type&JS_EVENT_AXIS) aval[ev.number]=ev.value; } print_data(aval, bval, axes, btns); nobutton=0; for (i=0; i<btns; i++) nobutton+=bval[i]; } //set initial deadzone for (i=0; i<axes; i++) dmin[i]=dmax[i]=aval[i]; nobutton=0; //wait five seconds for scan of deadzone count=0; while (count<500) { while (read(fd, &ev, sizeof(ev))==sizeof(ev)) { if (ev.type&JS_EVENT_BUTTON) bval[ev.number]=ev.value; if (ev.type&JS_EVENT_AXIS) { aval[ev.number]=ev.value; if (aval[ev.number]<dmin[ev.number]) dmin[ev.number]=aval[ev.number]; if (aval[ev.number]>dmax[ev.number]) dmax[ev.number]=aval[ev.number]; } } print_data(aval, bval, axes, btns); usleep(1000); count++; } for (i=0; i<axes; i++) min[i]=max[i]=aval[i]; printf("\n\n"); printf("Move axes through complete range of motion.\n"); printf("Press a button when complete\n"); print_data_hdr(aval, bval, axes, btns); while (nobutton==0) { while (read(fd, &ev, sizeof(ev))==sizeof(ev)) { if (ev.type&JS_EVENT_BUTTON) bval[ev.number]=ev.value; if (ev.type&JS_EVENT_AXIS) { aval[ev.number]=ev.value; if (aval[ev.number]<min[ev.number]) min[ev.number]=aval[ev.number]; if (aval[ev.number]>max[ev.number]) max[ev.number]=aval[ev.number]; } } print_data(aval, bval, axes, btns); nobutton=0; for (i=0; i<btns; i++) nobutton+=bval[i]; } printf("\n"); for (i=0; i<axes; i++) { cor[i].type=JS_CORR_BROKEN; printf("%d: %d %d %d %d\n", i, dmin[i], dmax[i], min[i], max[i]); if (max[i]==dmax[i]) dmax[i]=max[i]-1; if (min[i]==dmin[i]) dmin[i]=min[i]+1; cor[i].coef[0]=dmin[i]; cor[i].coef[1]=dmax[i]; cor[i].coef[2]=32768*16384/(dmin[i]-min[i]); cor[i].coef[3]=32768*16384/(max[i]-dmax[i]); } ioctl(fd, JSIOCSCORR, cor); return 0; }