25 static const char offset = 0x21;
26 static const double REV_PER_TICK = 1.0/4096;
29 #define STATUS_RESETTING (-1) // Resetting the box 30 #define STATUS_SYNCING (0) // Looking for the first character of report 31 #define STATUS_READING (1) // Looking for the rest of the report 33 #define MAX_TIME_INTERVAL (2000000) // max time between reports (usec) 40 const char * port,
int baud,
41 const int numbuttons,
const int numchannels,
const int numencoders):
45 _numbuttons(numbuttons),
46 _numchannels(numchannels),
47 _numencoders(numencoders)
51 fprintf(stderr,
"vrpn_CerealBox: Can only support 24 buttons, not %d\n",
56 fprintf(stderr,
"vrpn_CerealBox: Can only support 8 analogs, not %d\n",
61 fprintf(stderr,
"vrpn_CerealBox: Can only support 8 encoders, not %d\n",
99 struct timeval timeout;
100 unsigned char inbuf[45];
101 const char *Cpy =
"Copyright (c), BG Systems";
102 int major, minor, bug;
103 unsigned char reset_str[32];
122 perror(
"vrpn_CerealBox: Error reading from box\n");
126 fprintf(stderr,
"vrpn_CerealBox: No response from box\n");
130 fprintf(stderr,
"vrpn_CerealBox: Got %d of 44 expected characters\n",ret);
136 if (strncmp((
char *)inbuf, Cpy, strlen(Cpy))) {
137 fprintf(stderr,
"vrpn_CerealBox: Copyright string mismatch: %s\n",inbuf);
140 major = inbuf[38] -
'0';
141 minor = inbuf[40] -
'0';
142 bug = inbuf[41] -
'0';
143 if ( (3 != major) || (0 != minor) || (7 != bug) ) {
144 fprintf(stderr,
"vrpn_CerealBox: Bad EEPROM version (want 3.07, got %d.%d%d)\n",
148 printf(
"vrpn_CerealBox: Box of type %c found\n",inbuf[42]);
162 for (i = 0; i < 4; i++) {
167 for (i = 0; i < 4; i++) {
175 dig1_3 |= (1 << (i/8));
179 for (i = 0; i < 4; i++) {
184 for (i = 0; i < 4; i++) {
191 reset_str[1] = (
unsigned char)(ana1_4 + offset);
192 reset_str[2] = (
unsigned char)((ana5_8 | (dig1_3 << 4)) + offset);
193 reset_str[3] = (
unsigned char)(0 + offset);
194 reset_str[4] = (
unsigned char)(0 + offset);
195 reset_str[5] = (
unsigned char)(enc1_4 + offset);
196 reset_str[6] = (
unsigned char)(enc1_4 + offset);
197 reset_str[7] = (
unsigned char)(enc5_8 + offset);
198 reset_str[8] = (
unsigned char)(enc5_8 + offset);
209 perror(
"vrpn_CerealBox: Error reading ack from box\n");
213 fprintf(stderr,
"vrpn_CerealBox: No ack from box\n");
217 fprintf(stderr,
"vrpn_CerealBox: Got %d of 2 expected ack characters\n",ret);
220 if (inbuf[0] !=
'a') {
221 fprintf(stderr,
"vrpn_CerealBox: Bad ack: wanted 'a', got '%c'\n",inbuf[0]);
229 printf(
"CerealBox reset complete.\n");
279 fprintf(stderr,
"vrpn_CerealBox: Syncing (looking for 'p', " 293 printf(
"... Got the 1st char\n");
315 if (ret != 0) printf(
"... got %d characters (%d total)\n",ret,
_bufcount);
331 fprintf(stderr,
"vrpn_CerealBox: Not 'p' in record\n");
336 fprintf(stderr,
"vrpn_CerealBox: No carriage return in record\n");
372 for (i = numbuttonchars-1; i >= 0; i--) {
375 char bits = (char)(
_buffer[nextchar++] - offset);
378 buttons[ i*4 + 3 ] = ( (bits & 0x08) != 0);
379 buttons[ i*4 + 2 ] = ( (bits & 0x04) != 0);
380 buttons[ i*4 + 1 ] = ( (bits & 0x02) != 0);
381 buttons[ i*4 + 0 ] = ( (bits & 0x01) != 0);
392 intval = (0x3f & (
_buffer[nextchar++]-offset)) << 6;
393 intval |= (0x3f & (
_buffer[nextchar++]-offset));
394 realval = -1.0 + (2.0 * intval/4095.0);
406 int enc0, enc1, enc2, enc3;
409 enc0 = (
_buffer[nextchar++]-offset) & 0x3f;
411 enc1 = (
_buffer[nextchar++]-offset) & 0x3f;
412 increment |= enc1 << 6;
413 enc2 = (
_buffer[nextchar++]-offset) & 0x3f;
414 increment |= enc2 << 12;
415 enc3 = (
_buffer[nextchar++]-offset) & 0x3f;
416 increment |= enc3 << 18;
417 if ( increment & 0x800000 ) {
418 dials[i] = (int)(increment - 16777216) * REV_PER_TICK;
420 dials[i] = (int)(increment) * REV_PER_TICK;
483 struct timeval current_time;
486 fprintf(stderr,
"CerealBox failed to read... current_time=%ld:%ld, timestamp=%ld:%ld\n",
487 current_time.tv_sec, static_cast<long>(current_time.tv_usec),
496 fprintf(stderr,
"vrpn_CerealBox: Unknown mode (internal error)\n");
#define MAX_TIME_INTERVAL
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
int vrpn_write_characters(int comm, const unsigned char *buffer, size_t bytes)
Write the buffer to the serial port.
virtual void report_changes(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report only if something has changed (for servers) Optionally, tell what time to stamp the val...
virtual void report_changes(void)
int vrpn_flush_input_buffer(int comm)
Throw out any characters within the input buffer.
vrpn_Serial: Pulls all the serial port routines into one file to make porting to new operating system...
vrpn_float64 channel[vrpn_CHANNEL_MAX]
unsigned char _buffer[512]
Generic connection class not specific to the transport mechanism.
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 ...
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
All types of client/server/peer objects in VRPN should be derived from the vrpn_BaseClass type descri...
int vrpn_read_available_characters(int comm, unsigned char *buffer, size_t bytes)
virtual void clear_values(void)
virtual void report(void)
int send_text_message(const char *msg, struct timeval timestamp, vrpn_TEXT_SEVERITY type=vrpn_TEXT_NORMAL, vrpn_uint32 level=0)
Sends a NULL-terminated text message from the device d_sender_id.
vrpn_CerealBox(const char *name, vrpn_Connection *c, const char *port, int baud, const int numbuttons, const int numchannels, const int numencoders)
#define vrpn_gettimeofday
virtual int get_report(void)
unsigned long vrpn_TimevalDuration(struct timeval endT, struct timeval startT)
Return number of microseconds between startT and endT.
vrpn_float64 last[vrpn_CHANNEL_MAX]
vrpn_float64 dials[vrpn_DIAL_MAX]