~ubuntu-branches/ubuntu/saucy/joystick/saucy-proposed

« back to all changes in this revision

Viewing changes to utils/ffcfstress.c

  • Committer: Package Import Robot
  • Author(s): Stephen Kitt
  • Date: 2013-05-06 23:03:26 UTC
  • mfrom: (3.1.12 sid)
  • Revision ID: package-import@ubuntu.com-20130506230326-po18icz4mtaa25k1
Tags: 1:1.4.6-1
* New upstream release:
  - Disable CRTSCTS on ELO touchscreens. Closes: #699030. Thanks Thierry
    Bultel!
  - Handle long device names correctly. Closes: #706744. Thanks Ralf
    Jung!
* Drop hardening.patch, merged upstream.
* Standards-Version 3.9.4, no change required.
* Switch to my Debian address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include <errno.h>
32
32
#include <math.h>
33
33
 
34
 
 
35
 
/* Helper for testing large bit masks */
36
 
#define TEST_BIT(bit,bits) (((bits[bit>>5]>>(bit&0x1f))&1)!=0)
 
34
#include "bitmaskros.h"
37
35
 
38
36
 
39
37
/* Default values for the options */
42
40
#define DEFAULT_MOTION_FREQUENCY  0.1
43
41
#define DEFAULT_MOTION_AMPLITUDE  1.0
44
42
#define DEFAULT_SPRING_STRENGTH   1.0
 
43
#define DEFAULT_AXIS_INDEX          0
 
44
#define DEFAULT_AXIS_CODE       ABS_X
45
45
 
 
46
static const char* axis_names[] = { "X", "Y", "Z", "RX", "RY", "RZ", "WHEEL" };
 
47
static const int axis_codes[] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ, ABS_WHEEL };
46
48
 
47
49
/* Options */
48
50
const char * device_name = DEFAULT_DEVICE_NAME;
50
52
double motion_frequency  = DEFAULT_MOTION_FREQUENCY;
51
53
double motion_amplitude  = DEFAULT_MOTION_AMPLITUDE;
52
54
double spring_strength   = DEFAULT_SPRING_STRENGTH;
 
55
int    axis_index        = DEFAULT_AXIS_INDEX;
 
56
int    axis_code         = DEFAULT_AXIS_CODE;
53
57
int stop_and_play = 0;  /* Stop-upload-play effects instead of updating */
 
58
int autocenter_off = 0; /* switch the autocentering off */
54
59
 
55
60
 
56
61
/* Global variables about the initialized device */
57
62
int device_handle;
58
 
int axis_code, axis_min, axis_max;
 
63
int axis_min, axis_max;
59
64
struct ff_effect effect;
60
65
 
61
66
 
64
69
{
65
70
        int i;
66
71
 
67
 
        if (argc<2) goto l_help;
68
 
 
69
 
        for (i=1; i<argc; i++) {
70
 
                if      (!strcmp(argv[i],"-d") && i<argc-1) device_name     =argv[++i];
71
 
                else if (!strcmp(argv[i],"-u") && i<argc-1) update_rate     =atof(argv[++i]);
72
 
                else if (!strcmp(argv[i],"-f") && i<argc-1) motion_frequency=atof(argv[++i]);
73
 
                else if (!strcmp(argv[i],"-a") && i<argc-1) motion_amplitude=atof(argv[++i]);
74
 
                else if (!strcmp(argv[i],"-s") && i<argc-1) spring_strength =atof(argv[++i]);
75
 
                else if (!strcmp(argv[i],"-o")) ;
76
 
                else goto l_help;
77
 
        }
78
 
        return;
79
 
 
80
 
l_help:
81
 
        printf("-------- ffcfstress - Force Feedback: Constant Force Stress Test --------\n");
82
 
        printf("Description:\n");
83
 
        printf("  This program is for stress testing constant non-enveloped forces on\n");
84
 
        printf("  a force feedback device via the event interface. It simulates a\n");
85
 
        printf("  moving spring force by a frequently updated constant force effect.\n");
86
 
        printf("  BE CAREFUL IN USAGE, YOUR DEVICE MAY GET DAMAGED BY THE STRESS TEST!\n");
87
 
        printf("Usage:\n");
88
 
        printf("  %s <option> [<option>...]\n",argv[0]);
89
 
        printf("Options:\n");
90
 
        printf("  -d <string>  device name (default: %s)\n",DEFAULT_DEVICE_NAME);
91
 
        printf("  -u <double>  update rate in Hz (default: %.2f)\n",DEFAULT_UPDATE_RATE);
92
 
        printf("  -f <double>  spring center motion frequency in Hz (default: %.2f)\n",DEFAULT_MOTION_FREQUENCY);
93
 
        printf("  -a <double>  spring center motion amplitude 0.0..1.0 (default: %.2f)\n",DEFAULT_MOTION_AMPLITUDE);
94
 
        printf("  -s <double>  spring strength factor (default: %.2f)\n",DEFAULT_SPRING_STRENGTH);
95
 
        printf("  -o           dummy option (useful because at least one option is needed)\n");
96
 
        exit(1);
 
72
        int help = (argc < 2);
 
73
 
 
74
        for (i=1; i<argc && !help; i++) {
 
75
                if (!strcmp(argv[i],"-d")) {
 
76
                        if (i<argc-1) device_name = argv[++i]; else help = 1;
 
77
                } else if (!strcmp(argv[i],"-u")) {
 
78
                        if (i<argc-1) update_rate = atof(argv[++i]); else help = 1;
 
79
                } else if (!strcmp(argv[i],"-f")) {
 
80
                        if (i<argc-1) motion_frequency=atof(argv[++i]); else help = 1;
 
81
                } else if (!strcmp(argv[i],"-a")) {
 
82
                        if (i<argc-1) motion_amplitude=atof(argv[++i]); else help = 1;
 
83
                } else if (!strcmp(argv[i],"-s")) {
 
84
                        if (i<argc-1) spring_strength =atof(argv[++i]); else help = 1;
 
85
                } else if (!strcmp(argv[i],"-x")) {
 
86
                        if (i<argc-1) { 
 
87
                                axis_index = atoi(argv[++i]); 
 
88
                                if (axis_index < 0 || axis_index >= sizeof(axis_names)/sizeof(char*))
 
89
                                    help = 1;
 
90
                                else
 
91
                                    axis_code = axis_codes[axis_index];
 
92
                        } else help = 1;
 
93
                } else if (!strcmp(argv[i],"-o")) {
 
94
                        ;
 
95
                } else if (!strcmp(argv[i],"-A")) {
 
96
                        autocenter_off = 1;
 
97
                } else help = 1;
 
98
        }
 
99
 
 
100
 
 
101
        if (help) {
 
102
                printf("-------- ffcfstress - Force Feedback: Constant Force Stress Test --------\n");
 
103
                printf("Description:\n");
 
104
                printf("  This program is for stress testing constant non-enveloped forces on\n");
 
105
                printf("  a force feedback device via the event interface. It simulates a\n");
 
106
                printf("  moving spring force by a frequently updated constant force effect.\n");
 
107
                printf("  BE CAREFUL IN USAGE, YOUR DEVICE MAY GET DAMAGED BY THE STRESS TEST!\n");
 
108
                printf("Usage:\n");
 
109
                printf("  %s <option> [<option>...]\n",argv[0]);
 
110
                printf("Options:\n");
 
111
                printf("  -d <string>  device name (default: %s)\n",DEFAULT_DEVICE_NAME);
 
112
                printf("  -u <double>  update rate in Hz (default: %.2f)\n",DEFAULT_UPDATE_RATE);
 
113
                printf("  -f <double>  spring center motion frequency in Hz (default: %.2f)\n",DEFAULT_MOTION_FREQUENCY);
 
114
                printf("  -a <double>  spring center motion amplitude 0.0..1.0 (default: %.2f)\n",DEFAULT_MOTION_AMPLITUDE);
 
115
                printf("  -s <double>  spring strength factor (default: %.2f)\n",DEFAULT_SPRING_STRENGTH);
 
116
                printf("  -x <int>     absolute axis to test (default: %d=%s)\n",DEFAULT_AXIS_INDEX, axis_names[DEFAULT_AXIS_INDEX]);
 
117
                printf("               (0 = X, 1 = Y, 2 = Z, 3 = RX, 4 = RY, 5 = RZ, 6 = WHEEL)\n");
 
118
                printf("  -A           switch off auto-centering\n");
 
119
                printf("  -o           dummy option (useful because at least one option is needed)\n");
 
120
                exit(1);
 
121
        }
97
122
}
98
123
 
99
124
 
 
125
 
100
126
/* Initialize device, create constant force effect */
101
127
void init_device()
102
128
{
103
 
        unsigned long key_bits[32],abs_bits[32],ff_bits[32];
 
129
        unsigned char key_bits[1 + KEY_MAX/8/sizeof(unsigned char)];
 
130
        unsigned char abs_bits[1 + ABS_MAX/8/sizeof(unsigned char)];
 
131
        unsigned char ff_bits[1 + FF_MAX/8/sizeof(unsigned char)];
 
132
 
104
133
        struct input_event event;
105
 
        int valbuf[16];
 
134
        struct input_absinfo absinfo;
106
135
 
107
136
        /* Open event device with write permission */
108
137
        device_handle = open(device_name,O_RDWR|O_NONBLOCK);
113
142
        }
114
143
 
115
144
        /* Which buttons has the device? */
116
 
        memset(key_bits,0,32*sizeof(unsigned long));
117
 
        if (ioctl(device_handle,EVIOCGBIT(EV_KEY,32*sizeof(unsigned long)),key_bits)<0) {
 
145
        memset(key_bits,0,sizeof(key_bits));
 
146
        if (ioctl(device_handle,EVIOCGBIT(EV_KEY,sizeof(key_bits)),key_bits)<0) {
118
147
                fprintf(stderr,"ERROR: can not get key bits (%s) [%s:%d]\n",
119
148
                        strerror(errno),__FILE__,__LINE__);
120
149
                exit(1);
121
150
        }
122
151
 
123
152
        /* Which axes has the device? */
124
 
        memset(abs_bits,0,32*sizeof(unsigned long));
125
 
        if (ioctl(device_handle,EVIOCGBIT(EV_ABS,32*sizeof(unsigned long)),abs_bits)<0) {
 
153
        memset(abs_bits,0,sizeof(abs_bits));
 
154
        if (ioctl(device_handle,EVIOCGBIT(EV_ABS,sizeof(abs_bits)),abs_bits)<0) {
126
155
                fprintf(stderr,"ERROR: can not get abs bits (%s) [%s:%d]\n",
127
156
                        strerror(errno),__FILE__,__LINE__);
128
157
                exit(1);
129
158
        }
130
159
 
131
160
        /* Now get some information about force feedback */
132
 
        memset(ff_bits,0,32*sizeof(unsigned long));
133
 
        if (ioctl(device_handle,EVIOCGBIT(EV_FF ,32*sizeof(unsigned long)),ff_bits)<0) {
 
161
        memset(ff_bits,0,sizeof(ff_bits));
 
162
        if (ioctl(device_handle,EVIOCGBIT(EV_FF ,sizeof(ff_bits)),ff_bits)<0) {
134
163
                fprintf(stderr,"ERROR: can not get ff bits (%s) [%s:%d]\n",
135
164
                        strerror(errno),__FILE__,__LINE__);
136
165
                exit(1);
137
166
        }
138
167
 
139
 
        /* Which axis is the x-axis? */
140
 
        if      (TEST_BIT(ABS_X    ,abs_bits)) axis_code=ABS_X;
141
 
        else if (TEST_BIT(ABS_RX   ,abs_bits)) axis_code=ABS_RX;
142
 
        else if (TEST_BIT(ABS_WHEEL,abs_bits)) axis_code=ABS_WHEEL;
143
 
        else {
144
 
                fprintf(stderr,"ERROR: no suitable x-axis found [%s:%d]\n",
145
 
                        __FILE__,__LINE__);
 
168
        /* Check if selected axis is available */
 
169
        if (!testBit(axis_code, abs_bits)) {
 
170
                fprintf(stderr,"ERROR: selected axis %s not available [%s:%d] (see available ones with fftest)\n",
 
171
                        axis_names[axis_index], __FILE__,__LINE__);
146
172
                exit(1);
147
173
        }
148
174
 
149
175
        /* get axis value range */
150
 
        if (ioctl(device_handle,EVIOCGABS(axis_code),valbuf)<0) {
 
176
        if (ioctl(device_handle,EVIOCGABS(axis_code),&absinfo)<0) {
151
177
                fprintf(stderr,"ERROR: can not get axis value range (%s) [%s:%d]\n",
152
178
                        strerror(errno),__FILE__,__LINE__);
153
179
                exit(1);
154
180
        }
155
 
        axis_min=valbuf[1];
156
 
        axis_max=valbuf[2];
 
181
        axis_min=absinfo.minimum;
 
182
        axis_max=absinfo.maximum;
157
183
        if (axis_min>=axis_max) {
158
184
                fprintf(stderr,"ERROR: bad axis value range (%d,%d) [%s:%d]\n",
159
185
                        axis_min,axis_max,__FILE__,__LINE__);
161
187
        }
162
188
 
163
189
        /* force feedback supported? */
164
 
        if (!TEST_BIT(FF_CONSTANT,ff_bits)) {
165
 
                fprintf(stderr,"ERROR: device (or driver) has no force feedback support [%s:%d]\n",
 
190
        if (!testBit(FF_CONSTANT,ff_bits)) {
 
191
                fprintf(stderr,"ERROR: device (or driver) has no constant force feedback support [%s:%d]\n",
166
192
                        __FILE__,__LINE__);
167
193
                exit(1);
168
194
        }
169
195
 
170
196
        /* Switch off auto centering */
171
 
        memset(&event,0,sizeof(event));
172
 
        event.type=EV_FF;
173
 
        event.code=FF_AUTOCENTER;
174
 
        event.value=0;
175
 
        if (write(device_handle,&event,sizeof(event))!=sizeof(event)) {
176
 
                fprintf(stderr,"ERROR: failed to disable auto centering (%s) [%s:%d]\n",
177
 
                        strerror(errno),__FILE__,__LINE__);
178
 
                exit(1);
 
197
        if (autocenter_off) {
 
198
                memset(&event,0,sizeof(event));
 
199
                event.type=EV_FF;
 
200
                event.code=FF_AUTOCENTER;
 
201
                event.value=0;
 
202
                if (write(device_handle,&event,sizeof(event))!=sizeof(event)) {
 
203
                        fprintf(stderr,"ERROR: failed to disable auto centering (%s) [%s:%d]\n",
 
204
                                strerror(errno),__FILE__,__LINE__);
 
205
                        exit(1);
 
206
                }
179
207
        }
180
208
 
181
209
        /* Initialize constant force effect */
230
258
 
231
259
        /* Set force */
232
260
        if (force>1.0) force=1.0;
233
 
        if (force<-1.0) force=1.0;
234
 
        effect.u.constant.level=(short)(force*32767.0); /* only to be safe */
 
261
        else if (force<-1.0) force=-1.0;
 
262
        effect.u.constant.level=(short)(force*32767.0);
235
263
        effect.direction=0xC000;
236
264
        effect.u.constant.envelope.attack_level=(short)(force*32767.0); /* this one counts! */
237
265
        effect.u.constant.envelope.fade_level=(short)(force*32767.0); /* only to be safe */