25static const char offset = 0x21;
26static const double REV_PER_TICK = 1.0/4096;
29#define STATUS_RESETTING (-1)
30#define STATUS_SYNCING (0)
31#define STATUS_READING (1)
33#define MAX_TIME_INTERVAL (2000000)
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",
102 struct timeval timeout;
103 unsigned char inbuf[45];
104 const char *Cpy =
"Copyright (c), BG Systems";
105 int major, minor, bug;
106 unsigned char reset_str[32];
125 perror(
"vrpn_CerealBox: Error reading from box\n");
129 fprintf(stderr,
"vrpn_CerealBox: No response from box\n");
133 fprintf(stderr,
"vrpn_CerealBox: Got %d of 44 expected characters\n",ret);
139 if (strncmp((
char *)inbuf, Cpy, strlen(Cpy))) {
140 fprintf(stderr,
"vrpn_CerealBox: Copyright string mismatch: %s\n",inbuf);
143 major = inbuf[38] -
'0';
144 minor = inbuf[40] -
'0';
145 bug = inbuf[41] -
'0';
146 if ( (3 != major) || (0 != minor) || (7 != bug) ) {
147 fprintf(stderr,
"vrpn_CerealBox: Bad EEPROM version (want 3.07, got %d.%d%d)\n",
151 printf(
"vrpn_CerealBox: Box of type %c found\n",inbuf[42]);
165 for (i = 0; i < 4; i++) {
170 for (i = 0; i < 4; i++) {
178 dig1_3 |= (1 << (i/8));
182 for (i = 0; i < 4; i++) {
187 for (i = 0; i < 4; i++) {
194 reset_str[1] = (
unsigned char)(ana1_4 + offset);
195 reset_str[2] = (
unsigned char)((ana5_8 | (dig1_3 << 4)) + offset);
196 reset_str[3] = (
unsigned char)(0 + offset);
197 reset_str[4] = (
unsigned char)(0 + offset);
198 reset_str[5] = (
unsigned char)(enc1_4 + offset);
199 reset_str[6] = (
unsigned char)(enc1_4 + offset);
200 reset_str[7] = (
unsigned char)(enc5_8 + offset);
201 reset_str[8] = (
unsigned char)(enc5_8 + offset);
212 perror(
"vrpn_CerealBox: Error reading ack from box\n");
216 fprintf(stderr,
"vrpn_CerealBox: No ack from box\n");
220 fprintf(stderr,
"vrpn_CerealBox: Got %d of 2 expected ack characters\n",ret);
223 if (inbuf[0] !=
'a') {
224 fprintf(stderr,
"vrpn_CerealBox: Bad ack: wanted 'a', got '%c'\n",inbuf[0]);
232 printf(
"CerealBox reset complete.\n");
282 fprintf(stderr,
"vrpn_CerealBox: Syncing (looking for 'p', "
296 printf(
"... Got the 1st char\n");
318 if (ret != 0) printf(
"... got %d characters (%d total)\n",ret,
_bufcount);
334 fprintf(stderr,
"vrpn_CerealBox: Not 'p' in record\n");
339 fprintf(stderr,
"vrpn_CerealBox: No carriage return in record\n");
375 for (i = numbuttonchars-1; i >= 0; i--) {
378 char bits = (char)(
_buffer[nextchar++] - offset);
381 buttons[ i*4 + 3 ] = ( (bits & 0x08) != 0);
382 buttons[ i*4 + 2 ] = ( (bits & 0x04) != 0);
383 buttons[ i*4 + 1 ] = ( (bits & 0x02) != 0);
384 buttons[ i*4 + 0 ] = ( (bits & 0x01) != 0);
395 intval = (0x3f & (
_buffer[nextchar++]-offset)) << 6;
396 intval |= (0x3f & (
_buffer[nextchar++]-offset));
397 realval = -1.0 + (2.0 * intval/4095.0);
409 int enc0, enc1, enc2, enc3;
412 enc0 = (
_buffer[nextchar++]-offset) & 0x3f;
414 enc1 = (
_buffer[nextchar++]-offset) & 0x3f;
415 increment |= enc1 << 6;
416 enc2 = (
_buffer[nextchar++]-offset) & 0x3f;
417 increment |= enc2 << 12;
418 enc3 = (
_buffer[nextchar++]-offset) & 0x3f;
419 increment |= enc3 << 18;
420 if ( increment & 0x800000 ) {
421 dials[i] = (int)(increment - 16777216) * REV_PER_TICK;
423 dials[i] = (int)(increment) * REV_PER_TICK;
486 struct timeval current_time;
489 fprintf(stderr,
"CerealBox failed to read... current_time=%ld:%ld, timestamp=%ld:%ld\n",
490 current_time.tv_sec,
static_cast<long>(current_time.tv_usec),
499 fprintf(stderr,
"vrpn_CerealBox: Unknown mode (internal error)\n");
vrpn_float64 last[vrpn_CHANNEL_MAX]
vrpn_float64 channel[vrpn_CHANNEL_MAX]
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 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...
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
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)
unsigned char _buffer[512]
virtual void clear_values(void)
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
virtual int get_report(void)
Generic connection class not specific to the transport mechanism.
virtual void report_changes(void)
vrpn_float64 dials[vrpn_DIAL_MAX]
virtual void report(void)
#define MAX_TIME_INTERVAL
All types of client/server/peer objects in VRPN should be derived from the vrpn_BaseClass type descri...
int vrpn_write_characters(int comm, const unsigned char *buffer, size_t bytes)
Write the buffer to the serial port.
int vrpn_flush_input_buffer(int comm)
Throw out any characters within the input buffer.
int vrpn_read_available_characters(int comm, unsigned char *buffer, size_t bytes)
vrpn_Serial: Pulls all the serial port routines into one file to make porting to new operating system...
unsigned long vrpn_TimevalDuration(struct timeval endT, struct timeval startT)
Return number of microseconds between startT and endT.
#define vrpn_gettimeofday