vrpn 07.35
Virtual Reality Peripheral Network
Loading...
Searching...
No Matches
vrpn_Atmel.C
Go to the documentation of this file.
1/***************************************************************************************************/
2/* */
3/* Copyright (C) 2003 Bauhaus University Weimar */
4/* Released into the public domain on 6/23/2007 as part of the VRPN project */
5/* by Jan P. Springer. */
6/* */
7/***************************************************************************************************/
8/* */
9/* module : vrpn_Atmel */
10/* project : vrpn_Avango */
11/* description: server for microcontroller based on Atmel chip */
12/* hardware developed by Albotronic: www.albotronic.de */
13/* */
14/***************************************************************************************************/
15
16#ifndef _WIN32
17
18#include <errno.h> // for errno
19#include <stdio.h> // for fprintf, stderr, printf, etc
20#include <stdlib.h> // for exit
21#include <sys/select.h> // for select, FD_SET, FD_ZERO, etc
22#include <vrpn_Shared.h> // for vrpn_gettimeofday
23
24#include "vrpn_Atmel.h"
25#include "vrpn_Connection.h" // for vrpn_Connection
26#include "vrpn_Types.h" // for vrpn_float64
27#include "vrpn_atmellib.h" // for getRegister, closePort, etc
28#include "vrpn_atmellib_errno.h" // for ATMELLIB_NOERROR
29
30#include <termios.h> // for tcflush, TCIOFLUSH, termios
31
32#include <string.h> // for strerror
33
34/***************************************************************************************************/
35/***************************************************************************************************/
36namespace {
37
38struct termios init_params;
39struct timeval wait;
40
41/***************************************************************************************************/
42// check if there if the Atmel is connected to the serial
43/***************************************************************************************************/
44bool
45check_serial(int fd)
46{
47 int ret=0;
48
49 // make a new fd set to watch
50 fd_set rfds;
51
52 // clear the set
53 FD_ZERO( &rfds );
54 // ad the current fd to the set
55 FD_SET( fd, &rfds );
56
57 wait.tv_sec = 5;
58 wait.tv_usec = 0;
59
60 ret = select( fd+1 , &rfds , 0 , 0 , &wait);
61
62 if (ret == 0) {
63
64 printf("Atmel not connected to the specified port.\n");
65 printf("Connect and try again.\n");
66
67 return false;
68 }
69 else if (ret<0) {
70
71 printf("Error while checking if Atmel is connected.\n");
72 printf("Error: %s (%i)\n", strerror(errno), errno );
73
74 return false;
75 }
76
77 printf("Atmel started.\n\n");
78
79 return true;
80}
81
82} // end of namespace
83
84/***************************************************************************************************/
85/* factory */
86/***************************************************************************************************/
87/* static */ vrpn_Atmel *
89 const char *port, long baud,
90 int channel_count ,
91 int * channel_mode)
92{
93 int fd;
94
95#ifdef VRPN_ATMEL_SERIAL_VRPN
96
97 if ( (fd=vrpn_open_commport(port, baud)) == -1) {
98
99 fprintf(stderr,"vrpn_Atmel: can't Open serial port\n");
100
101 return NULL;
102 }
103#else
104 // Open the serial port
105 if ( (fd=openPort(port, baud, &init_params)) == -1) {
106
107 fprintf(stderr,"vrpn_Atmel: can't Open serial port\n");
108
109 return NULL;
110 }
111
112 // look if the atmel is connected
113 if (! check_serial(fd) ) {
114
115 return NULL;
116 }
117#endif
118
119 vrpn_Atmel * self = NULL;
120 try { self = new vrpn_Atmel(name, c, fd); }
121 catch (...) { return NULL; }
122
123 if ( (self->vrpn_Analog_Server::setNumChannels(channel_count) != channel_count)
124 || (self->vrpn_Analog_Output_Server::setNumChannels(channel_count) != channel_count) ) {
125
126 fprintf(stderr,"vrpn_Atmel: the requested number of channels is not available\n");
127 try {
128 delete self;
129 } catch (...) {
130 fprintf(stderr, "vrpn_Atmel::Create(): delete failed\n");
131 return NULL;
132 }
133
134 return NULL;
135 }
136
137
138 // init the channels based on the infos given from the config file
139 self->init_channel_mode(channel_mode);
140
142
143 return self;
144}
145
146
147
148/***************************************************************************************************/
149/* constructor */
150/***************************************************************************************************/
151vrpn_Atmel::vrpn_Atmel(char* name, vrpn_Connection *c, int fd)
153 _status(VRPN_ATMEL_STATUS_ERROR),
154 serial_fd(fd)
155{
156 // find out what time it is - needed?
157 vrpn_gettimeofday(&timestamp, 0);
158 vrpn_gettimeofday(&_time_alive, 0);
159 vrpn_Analog::timestamp = timestamp;
160}
161
162
163/***************************************************************************************************/
164/* destructor */
165/***************************************************************************************************/
167{
168#ifdef VRPN_ATMEL_SERIAL_VRPN
169 vrpn_close_commport(serial_fd);
170#else
171 closePort(serial_fd , &init_params);
172#endif
173
174
175}
176
177/***************************************************************************************************/
178/* mainloop */
179/***************************************************************************************************/
180void
182{
183 if (_status == VRPN_ATMEL_STATUS_ERROR) {
184
185 return;
186 }
187
188 // o_num_channel is used as reference against num_channel
189 if (o_num_channel != num_channel) {
190
192 }
193
195
196 // get the pending messages so that the buffer to write down is updated
198
199 if ( ! d_connection->connected()) {
200
201 return;
202 }
203
204 // it's the first time we are in mainloop after
206
207 if (handle_new_connection()) {
208
210
211 fprintf(stderr,"vrpn_Atmel: mainloop()\n");
212 fprintf(stderr," new connection. status set to RUNNING\n");
213 }
214 else {
215
216 _status = VRPN_ATMEL_STATUS_ERROR;
217
218 fprintf(stderr,"vrpn_Atmel: mainloop()\n");
219 fprintf(stderr," error handling new connection. status set to ERROR\n");
220
221 return;
222 }
223
224 }
225
226 // do the read/write operations on the serial port
227 if ( ! mainloop_serial_io() ) {
228
229 fprintf(stderr,"vrpn_Atmel: mainloop()\n");
230 fprintf(stderr," error while io operations ERROR\n");
231
232 }
233
235 //vrpn_Analog::report_changes();
236
238}
239
240/***************************************************************************************************/
241/* check if the connection to the Atmel is still reliable */
242/***************************************************************************************************/
243bool
244vrpn_Atmel::Check_Serial_Alive()
245{
246 struct timeval look_time;
247
248 // check serial status every second
249 if ((timestamp.tv_sec - _time_alive.tv_sec) > VRPN_ATMEL_ALIVE_INTERVAL_SEC) {
250
251 // reset time alive
252 vrpn_gettimeofday(&_time_alive,0);
253
254 tcflush(serial_fd, TCIOFLUSH);
255
256 // make a new fd set to watch
257 fd_set rfds;
258
259 // clear the set
260 FD_ZERO( &rfds );
261 // ad the current fd to the set
262 FD_SET( serial_fd, &rfds );
263
264 look_time.tv_sec = VRPN_ATMEL_ALIVE_TIME_LOOK_SEC;
265 look_time.tv_usec = VRPN_ATMEL_ALIVE_TIME_LOOK_USEC;
266
267 if ((select( (serial_fd+1) , &rfds , 0 , 0 , &look_time)) <= 0) {
268
269 fprintf(stderr, "\nExiting...\n");
270
271 fprintf(stderr, "vrpn_Atmel::Check_Serial_Alive: connection timed out after (sec,msec):");
273 fprintf(stderr, "Killing Program!!!\n");
274
275 return false;
276 }
277
278#ifdef VRPN_ATMEL_VERBOSE
279 fprintf(stderr, "Connection still available...\n");
280#endif
281 }
282
283 return true;
284}
285
286/***************************************************************************************************/
287/* io operations on the serial port in mainloop */
288/***************************************************************************************************/
289bool
290vrpn_Atmel::mainloop_serial_io()
291{
292 vrpn_gettimeofday(&timestamp, 0);
293 vrpn_Analog::timestamp = timestamp;
294
295 // check if there is still a valid connection to the Chip
296 if (!Check_Serial_Alive()) {
297
298 // kill the program
299 // use e.g. a cron job to init the whole connection mechanism again
300 exit(0);
301 }
302
303 // do for all channels
304 for(int i=0; i<o_num_channel; ++i) {
305
307
308 // unused channel
309 continue;
310 }
311
312 // find out which channels have to been written down to the device
313 if (o_channel[i] != channel[i]) {
314
315 // test if channel is writable
316 if ( (_channel_mode[i] != VRPN_ATMEL_MODE_RW)
317 && (_channel_mode[i] != VRPN_ATMEL_MODE_WO) ) {
318
319 fprintf(stderr,"vrpn_Atmel: mainloop_serial_io()\n");
320 fprintf(stderr," channel not writable\n");
321
323
324 continue;
325 }
326
327 // test if it is a valid value: atmel uses 8 bit
328 if ((o_channel[i]<0) || (o_channel[i]>255)) {
329
330 fprintf(stderr,"vrpn_Atmel: mainloop_serial_io()\n");
331 fprintf(stderr," value out of range\n");
332
334
335 continue;
336 }
337
338 // try to write down
339 if (setRegister(serial_fd, i, (unsigned char) o_channel[i])
340 != ATMELLIB_NOERROR) {
341
342 fprintf(stderr,"vrpn_Atmel: mainloop_serial_io()\n");
343 fprintf(stderr," error writing down value, channel: %d\n",i);
344
346
347 continue;
348 }
349 else {
350
351 fprintf(stderr,"vrpn_Atmel: mainloop_serial_io()\n");
352 fprintf(stderr," written down value, channel: %d\n",i);
353 }
354
355 // no error
356 channel[i] = o_channel[i];
357
358 continue;
359 }
360
361 // this values are not requested for change -> read them
362
363 if ( (_channel_mode[i] == VRPN_ATMEL_MODE_RO)
364 || (_channel_mode[i] == VRPN_ATMEL_MODE_RW) ) {
365
366 if ( (channel[i] = getRegister(serial_fd, i)) < 0) {
367
368#ifdef VRPN_ATMEL_VERBOSE
369 fprintf(stderr, "Channel read: i=%i val=%f\n",i,channel[i]);
370
371 fprintf(stderr,"vrpn_Atmel: mainloop_serial_io()\n");
372 fprintf(stderr," error reading out value. channel=%d\n",i);
373#endif
374 // reset to the old value - don't send the error
375 // in some cases it's propably useful to know the error
377 //channel[i] = last[i];
378 }
379 }
380
381 } // end of for-loop
382
383 for(int i=0; i<o_num_channel ;++i) {
384
385 o_channel[i] = channel[i];
386 }
387
388 return true;
389}
390
391
392/***************************************************************************************************/
393/* init the io mode of the channels: */
394/***************************************************************************************************/
395void
396vrpn_Atmel::init_channel_mode(int * channel_mode)
397{
398 int val=0;
399
400 for(int i=0; i<o_num_channel; ++i) {
401
402 _channel_mode.push_back(channel_mode[i]);
403
404 if ( (channel_mode[i] == VRPN_ATMEL_MODE_RO)
405 || (_channel_mode[i] == VRPN_ATMEL_MODE_RW) ) {
406
407 // read the current value of the register
408 val=getRegister(serial_fd , i);
409 if (val < 0) {
410
411 // error while reading register value
412 fprintf(stderr,"vrpn_Atmel: init_channel_mode()\n");
413 fprintf(stderr," error reading out value: %i\n", val);
414
417 }
418 else {
419
420 channel[i] = (float) val;
421 o_channel[i] = (float) val;
422
423#ifdef VRPN_ATMEL_VERBOSE
424 fprintf(stderr, "vrpn_Atmel: i=%d val=%d\n",i ,val);
425#endif
426
427 }
428 }
429 else {
430
431 // channel is not for reading
434 }
435
436 } // end of for loop
437}
438
439
440/***************************************************************************************************/
441/* init the io mode of the channels: */
442/***************************************************************************************************/
443bool
444vrpn_Atmel::handle_new_connection()
445{
446 // request to send the current status of all registers
448
449 printf("\nconnection received.\n\n");
450
451 // really send the current status
453
454 return true;
455}
456
457#endif
458
vrpn_float64 o_channel[vrpn_CHANNEL_MAX]
vrpn_float64 channel[vrpn_CHANNEL_MAX]
Definition vrpn_Analog.h:38
struct timeval timestamp
Definition vrpn_Analog.h:41
vrpn_int32 num_channel
Definition vrpn_Analog.h:40
virtual void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report whether something has changed or not (for servers) Optionally, tell what time to stamp ...
Definition vrpn_Analog.C:94
void mainloop()
For this server, the user must normally call report() or report_changes() directly....
Definition vrpn_Atmel.C:181
static vrpn_Atmel * Create(char *name, vrpn_Connection *c, const char *port="/dev/ttyS0/", long baud=9600, int channel_count=0, int *channel_mode=NULL)
Definition vrpn_Atmel.C:88
vrpn_Connection * d_connection
Connection that this object talks to.
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
Generic connection class not specific to the transport mechanism.
virtual vrpn_bool connected(void) const
Returns vrpn_true if the connection has been established, vrpn_false if not (For a networkless connec...
virtual int mainloop(const struct timeval *timeout=NULL)=0
Call each time through program main loop to handle receiving any incoming messages and sending any pa...
#define VRPN_ATMEL_ALIVE_INTERVAL_SEC
Definition vrpn_Atmel.h:56
#define VRPN_ATMEL_MODE_RO
Definition vrpn_Atmel.h:43
#define VRPN_ATMEL_STATUS_RUNNING
Definition vrpn_Atmel.h:49
#define VRPN_ATMEL_STATUS_ERROR
Definition vrpn_Atmel.h:50
#define VRPN_ATMEL_ERROR_READING_IN
Definition vrpn_Atmel.h:38
#define VRPN_ATMEL_ALIVE_TIME_LOOK_SEC
Definition vrpn_Atmel.h:54
#define VRPN_ATMEL_MODE_WO
Definition vrpn_Atmel.h:45
#define VRPN_ATMEL_CHANNEL_NOT_VALID
Definition vrpn_Atmel.h:52
#define VRPN_ATMEL_ERROR_OUT_OF_RANGE
Definition vrpn_Atmel.h:40
#define VRPN_ATMEL_ALIVE_TIME_LOOK_USEC
Definition vrpn_Atmel.h:55
#define VRPN_ATMEL_ERROR_NOT_WRITABLE
Definition vrpn_Atmel.h:41
#define VRPN_ATMEL_STATUS_WAITING_FOR_CONNECTION
Definition vrpn_Atmel.h:48
#define VRPN_ATMEL_ERROR_WRITING_DOWN
Definition vrpn_Atmel.h:39
#define VRPN_ATMEL_MODE_RW
Definition vrpn_Atmel.h:44
int vrpn_close_commport(int comm)
int vrpn_open_commport(const char *portname, long baud, int charsize, vrpn_SER_PARITY parity, bool rts_flow)
Open a serial port, given its name and baud rate.
Definition vrpn_Serial.C:54
#define vrpn_gettimeofday
Definition vrpn_Shared.h:99