-
Notifications
You must be signed in to change notification settings - Fork 3
/
JS2Serial.c
268 lines (237 loc) · 5.25 KB
/
JS2Serial.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/* abgeleitet von Galileo Computing sdl9.c *
* compileflags: 'sdl-config --libs` `sdl-config --cflags` */
#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <termios.h>
#include "JS2Serial.h"
#include <fcntl.h>
#include <unistd.h>
/*********** RC alias *****************/
#define ROLL 0
#define PITCH 1
#define YAW 2
#define THROTTLE 3
#define AUX1 4
#define AUX2 5
#define AUX3 6
#define AUX4 7
static int16_t rcData[8]; // interval [1000;2000]
int serial;
static SDL_Joystick *js;
static void Joystick_Info (void)
{
int num_js, i;
num_js = SDL_NumJoysticks ();
printf ("Found %d Joystick(s)!\n",
num_js);
if (num_js == 0) {
printf ("Could find a Joystick!\n");
return;
}
/* Informationen zum Joystick */
for (i = 0; i < num_js; i++) {
js = SDL_JoystickOpen (i);
if (js == NULL) {
printf ("Cant open Joystick %d !\n", i);
}
else {
printf ("Joystick %d\n", i);
printf ("\tName: %s\n", SDL_JoystickName(i));
printf ("\tAxis: %i\n", SDL_JoystickNumAxes(js));
printf ("\tTrackballs: %i\n", SDL_JoystickNumBalls(js));
printf ("\tButtons: %i\n",SDL_JoystickNumButtons(js));
printf ("\tHats: %i\n",SDL_JoystickNumHats(js));
SDL_JoystickClose (js);
}
}
}
int16_t parsetoMultiWii(Sint16 value)
{
return (int16_t)(((((double)value)+32768.0)/65.536)+1000);
}
void readAxis(SDL_Event *event)
{
SDL_Event myevent = (SDL_Event)*event;
switch(myevent.jaxis.axis)
{
case ROLL_AXIS:
rcData[0]=parsetoMultiWii(myevent.jaxis.value);
break;
case PITCH_AXIS:
rcData[1]=parsetoMultiWii(myevent.jaxis.value);
break;
case YAW_AXIS:
rcData[2]=parsetoMultiWii(myevent.jaxis.value);
break;
case THROTTLE_AXIS:
rcData[3]=parsetoMultiWii(myevent.jaxis.value);
break;
case AUX1_AXIS:
rcData[4]=parsetoMultiWii(myevent.jaxis.value);
break;
case AUX2_AXIS:
rcData[5]=parsetoMultiWii(myevent.jaxis.value);
break;
case AUX3_AXIS:
rcData[6]=parsetoMultiWii(myevent.jaxis.value);
break;
case AUX4_AXIS:
rcData[7]=parsetoMultiWii(myevent.jaxis.value);
break;
default:
//do nothing
break;
}
}
static int eventloop_joystick (void)
{
SDL_Event event;
while (SDL_PollEvent (&event))
{
switch (event.type)
{
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE)
{
printf ("Hit ESCAPE to exit\n");
return 0;
}
break;
case SDL_JOYAXISMOTION:
//local
//~ printf ("Joystick %d, Axis %d moved to %d\n",
//~ event.jaxis.which, event.jaxis.axis, event.jaxis.value);
//prepare for serial output
readAxis(&event);
return 2;
break;
case SDL_JOYBUTTONUP:
case SDL_JOYBUTTONDOWN:
printf ("Joystick %i Button %i: %i\n",
event.jbutton.which, event.jbutton.button,
event.jbutton.state);
break;
case SDL_JOYHATMOTION:
printf ("Joystick %i Hat %i: %i\n",
event.jhat.which, event.jhat.hat, event.jhat.value);
break;
case SDL_QUIT:
return 0;
}
}
return 1;
}
void sendRC()
{
uint8_t checksum=0;
checksum^=16;
checksum^=200;
uint8_t i;
uint8_t z;
uint8_t outputbuffer[22];
//header
outputbuffer[0]='$';
outputbuffer[1]='M';
outputbuffer[2]='<';
//size
outputbuffer[3]=16;
//message type
outputbuffer[4]=200;
z=0;
for(i=5; i<21 ; i++)
{
//low byte
outputbuffer[i]=(uint8_t)(rcData[z]&0xFF);
checksum^=outputbuffer[i];
i++;
//high byte
outputbuffer[i]=(uint8_t)(rcData[z]>>8);
checksum^=outputbuffer[i];
z++;
}
outputbuffer[21]=checksum;
//~ //for debug use
//~ printf("send: ");
//~ int j;
//~ for(j=0;j<22;j++)
//~ {
//~ printf("%d-",outputbuffer[j]);
//~ }
//~ printf("\n rc= ");
//~ for(j=0;j<9;j++)
//~ {
//~ printf("%d-",rcData[j]);
//~ }
//~ printf("\n");
write(serial,outputbuffer,22);
//wait for serialport to send
tcdrain(serial);
}
int main (void)
{
//prefill with middle position
uint8_t i;
for(i=0; i<8 ; i++)
{
rcData[i]=1500;
}
//open serialport
serial = open ( SERIAL , O_RDWR | O_NOCTTY | O_NDELAY );
struct termios options;
//read current settings
tcgetattr(serial, &options);
//raw mode -> turn all the special features off
//+ use 8N1
cfmakeraw(&options);
//set baudrate
cfsetispeed(&options, BAUD);
cfsetospeed(&options, BAUD);
//enable receiving
options.c_cflag |=CREAD;
//minimum number of chars to read
options.c_cc[VMIN]=22;
//timeout reading
options.c_cc[VTIME]=2;
//no flowcontrol
#ifdef CNEW_RTSCTS
options.c_cflag &= ~CNEW_RTSCTS;
#endif
//write options
tcsetattr(serial, TCSANOW, &options);
int done = 1;
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_VIDEO) != 0)
{
printf ("Fehler: %s\n", SDL_GetError ());
return EXIT_FAILURE;
}
atexit (SDL_Quit);
Joystick_Info ();
js = SDL_JoystickOpen (JOYSTICK_N);
if (js == NULL)
{
printf("Couldn't open desired Joystick:%s\n",SDL_GetError());
done=0;
}
int res;
char buf[255];
while( done )
{
done = eventloop_joystick ();
if(done>1)
sendRC();
res = read(serial,buf,255);
if(res>0)
{
for(i=0;i<res;i++)
printf("%c",buf[i]);
printf("\n");
for(i=0;i<res;i++)
printf("%u|",buf[i]);
printf("\n");
}
}
SDL_JoystickClose (js);
close (serial);
return EXIT_SUCCESS;
}