CMUcam4 Arduino Interface Library  For Firmware Versions 1.00 - 1.03
Application Programmable Interface Online Documentation
 All Classes Files Functions Variables Macros Pages
CMUcam4.cpp
Go to the documentation of this file.
1 /***************************************************************************//**
2 * @file
3 * Portable %CMUcam4 interface library.
4 *
5 * @version @n 1.0
6 * @date @n 8/3/2012
7 *
8 * @authors @n Kwabena W. Agyeman & Christopher J. Leaf
9 * @copyright @n (c) 2012 Kwabena W. Agyeman & Christopher J. Leaf
10 * @n All rights reserved - Please see the end of the file for the terms of use
11 *
12 * @par Update History:
13 * @n v0.1 - Beta code - 3/20/2012
14 * @n v0.9 - Original release - 4/18/2012
15 * @n v1.0 - Documented and updated release - 8/3/2012
16 *******************************************************************************/
17 
18 #include "CMUcam4.h"
19 
20 /*******************************************************************************
21 * Constructor Functions
22 *******************************************************************************/
23 
25 {
26  CMUcom4 _copy;
27 
28  _state = DEACTIVATED;
29  _com = _copy;
30 }
31 
33 {
34  CMUcom4 _copy(port);
35 
36  _state = DEACTIVATED;
37  _com = _copy;
38 }
39 
40 /*******************************************************************************
41 * Helper Functions
42 *******************************************************************************/
43 
45  int row, int column)
46 {
47  if((pointer==NULL)||
50  {
52  }
53 
54  return ((pointer->pixels[(row * CMUCAM4_ID_T_C) + (column / 8)]
55  >> (7 - (column & 7))) & 1);
56 }
57 
59  int row, int column, int value)
60 {
61  int bitIndex; int byteIndex;
62 
63  if((pointer==NULL)||
66  {
68  }
69 
70  bitIndex = (7 - (column & 7));
71  byteIndex = ((row * CMUCAM4_ID_T_C) + (column / 8));
72 
73  pointer->pixels[byteIndex] =
74  (((~(1<<bitIndex))&(pointer->pixels[byteIndex]))|((value?1:0)<<bitIndex));
75 
77 }
78 
80  CMUcam4_image_data_t * source0,
81  CMUcam4_image_data_t * source1)
82 {
83  size_t index;
84 
85  if((destination == NULL) || (source0 == NULL) || (source1 == NULL))
86  {
88  }
89 
90  for(index = 0; index < CMUCAM4_ID_T_LENGTH; index++)
91  {
92  destination->pixels[index] =
93  (source0->pixels[index] & source1->pixels[index]);
94  }
95 
97 }
98 
100  CMUcam4_image_data_t * source0,
101  CMUcam4_image_data_t * source1)
102 {
103  size_t index;
104 
105  if((destination == NULL) || (source0 == NULL) || (source1 == NULL))
106  {
107  return CMUCAM4_RETURN_FAILURE;
108  }
109 
110  for(index = 0; index < CMUCAM4_ID_T_LENGTH; index++)
111  {
112  destination->pixels[index] =
113  (source0->pixels[index] | source1->pixels[index]);
114  }
115 
116  return CMUCAM4_RETURN_SUCCESS;
117 }
118 
120  CMUcam4_image_data_t * source0,
121  CMUcam4_image_data_t * source1)
122 {
123  size_t index;
124 
125  if((destination == NULL) || (source0 == NULL) || (source1 == NULL))
126  {
127  return CMUCAM4_RETURN_FAILURE;
128  }
129 
130  for(index = 0; index < CMUCAM4_ID_T_LENGTH; index++)
131  {
132  destination->pixels[index] =
133  (source0->pixels[index] ^ source1->pixels[index]);
134  }
135 
136  return CMUCAM4_RETURN_SUCCESS;
137 }
138 
140 {
141  size_t index;
142 
143  if(destination == NULL)
144  {
145  return CMUCAM4_RETURN_FAILURE;
146  }
147 
148  for(index = 0; index < CMUCAM4_ID_T_LENGTH; index++)
149  {
150  destination->pixels[index] =
151  (~destination->pixels[index]);
152  }
153 
154  return CMUCAM4_RETURN_SUCCESS;
155 }
156 
158 {
159  CMUcam4_entry_attributes_t * attributes;
160 
161  if(pointer == NULL)
162  {
163  return CMUCAM4_RETURN_FAILURE;
164  }
165 
166  attributes = ((CMUcam4_entry_attributes_t *) pointer->attributes);
167  return (attributes->readOnly == 'R');
168 }
169 
171 {
172  CMUcam4_entry_attributes_t * attributes;
173 
174  if(pointer == NULL)
175  {
176  return CMUCAM4_RETURN_FAILURE;
177  }
178 
179  attributes = ((CMUcam4_entry_attributes_t *) pointer->attributes);
180  return (attributes->hidden == 'H');
181 }
182 
184 {
185  CMUcam4_entry_attributes_t * attributes;
186 
187  if(pointer == NULL)
188  {
189  return CMUCAM4_RETURN_FAILURE;
190  }
191 
192  attributes = ((CMUcam4_entry_attributes_t *) pointer->attributes);
193  return (attributes->system == 'S');
194 }
195 
197 {
198  CMUcam4_entry_attributes_t * attributes;
199 
200  if(pointer == NULL)
201  {
202  return CMUCAM4_RETURN_FAILURE;
203  }
204 
205  attributes = ((CMUcam4_entry_attributes_t *) pointer->attributes);
206  return (attributes->volumeID == 'V');
207 }
208 
210 {
211  CMUcam4_entry_attributes_t * attributes;
212 
213  if(pointer == NULL)
214  {
215  return CMUCAM4_RETURN_FAILURE;
216  }
217 
218  attributes = ((CMUcam4_entry_attributes_t *) pointer->attributes);
219  return (attributes->directory == 'D');
220 }
221 
223 {
224  CMUcam4_entry_attributes_t * attributes;
225 
226  if(pointer == NULL)
227  {
228  return CMUCAM4_RETURN_FAILURE;
229  }
230 
231  attributes = ((CMUcam4_entry_attributes_t *) pointer->attributes);
232  return (attributes->archive == 'A');
233 }
234 
235 /*******************************************************************************
236 * State Functions
237 *******************************************************************************/
238 
240 {
241  int errorValue; int retVal0; int retVal1; static int resetTries;
242 
243  resetTries = CMUCAM4_RESET_TRIES;
244  errorValue = setjmp(_env);
245 
246  if(resetTries-- <= 0)
247  {
248  _com.end();
249  return errorValue;
250  }
251 
252  // Try to reset at fast, medium, and slow baud rates.
253 
254  _state = DEACTIVATED;
255  _setReadTimeout(CMUCAM4_RESET_TIMEOUT);
256 
257  _com.end();
258  _com.begin(CMUCOM4_FAST_BAUD_RATE);
259  _com.write((uint8_t) '\0');
260  _com.write((uint8_t) '\0');
261  _com.write((uint8_t) '\0');
262  _com.write("\rRS\r");
263 
264  _com.end();
265  _com.begin(CMUCOM4_MEDIUM_BAUD_RATE);
266  _com.write((uint8_t) '\0');
267  _com.write((uint8_t) '\0');
268  _com.write((uint8_t) '\0');
269  _com.write("\rRS\r");
270 
271  _com.end();
272  _com.begin(CMUCOM4_SLOW_BAUD_RATE);
273  _com.write((uint8_t) '\0');
274  _com.write((uint8_t) '\0');
275  _com.write((uint8_t) '\0');
276  _com.write("\rRS\r");
277 
278  // Get the firmware version.
279 
280  _waitForString("\rCMUcam4 v");
281  _readText();
282 
283  if(sscanf(_resBuffer, "%1d.%2d ", &retVal0, &retVal1) != 2)
284  {
285  longjmp(_env, CMUCAM4_UNEXPECTED_RESPONCE);
286  }
287 
288  _version = ((_CMUcam4_version) ((retVal0 * 100) + retVal1));
289 
290  switch(_version)
291  {
292  case VERSION_100: break;
293  case VERSION_101: break;
294  case VERSION_102: break;
295  case VERSION_103: break;
296 
297  default: longjmp(_env, CMUCAM4_UNSUPPORTED_VERSION); break;
298  }
299 
300  _waitForIdle();
301 
302  // Adjust the baud rate.
303 
304  _setReadTimeout(CMUCAM4_NON_FS_TIMEOUT);
305  _com.write("BM ");
306 
307  switch(_version)
308  {
309  case VERSION_100:
310  case VERSION_101: _com.write(CMUCOM4_MEDIUM_BR_STRING); break;
311  case VERSION_102:
312  case VERSION_103: _com.write(CMUCOM4_FAST_BR_STRING); break;
313  }
314 
315  _com.write((uint8_t) '\r');
316  _waitForResponce();
317  _com.end();
318 
319  switch(_version)
320  {
321  case VERSION_100:
322  case VERSION_101: _com.begin(CMUCOM4_MEDIUM_BAUD_RATE); break;
323  case VERSION_102:
324  case VERSION_103: _com.begin(CMUCOM4_FAST_BAUD_RATE); break;
325  }
326 
327  _com.write((uint8_t) '\r');
328  _waitForResponce();
329  _waitForIdle();
330 
331  // Adjust the stop bits.
332 
333  _setReadTimeout(CMUCAM4_NON_FS_TIMEOUT);
334  _com.write("DM ");
335 
336  switch(_version)
337  {
338  case VERSION_100:
339  case VERSION_101: _com.write(CMUCOM4_MEDIUM_SB_STRING); break;
340  case VERSION_102:
341  case VERSION_103: _com.write(CMUCOM4_FAST_SB_STRING); break;
342  }
343 
344  _com.write((uint8_t) '\r');
345  _waitForResponce();
346  _waitForIdle();
347 
348  _state = ACTIVATED;
349  return CMUCAM4_RETURN_SUCCESS;
350 }
351 
353 {
354  if(_state == DEACTIVATED)
355  {
356  return CMUCAM4_NOT_ACTIVATED;
357  }
358 
359  _state = DEACTIVATED;
360  _com.end();
361 }
362 
363 /*******************************************************************************
364 * System Level Commands
365 *******************************************************************************/
366 
368 {
369  return (_state == ACTIVATED) ? _version : CMUCAM4_NOT_ACTIVATED;
370 }
371 
373 {
374  return (_state == ACTIVATED) ? begin() : CMUCAM4_NOT_ACTIVATED;
375 }
376 
378 {
379  return _commandWrapper("SD\r", CMUCAM4_NON_FS_TIMEOUT);
380 }
381 
383 {
384  return _commandWrapper("SL\r", CMUCAM4_NON_FS_TIMEOUT);
385 }
386 
387 /*******************************************************************************
388 * Camera Module Commands
389 *******************************************************************************/
390 
391 int CMUcam4::cameraBrightness(int brightness)
392 {
393  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
394  "CB %d\r", brightness) < CMUCAM4_CMD_BUFFER_SIZE)
395  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
397 }
398 
399 int CMUcam4::cameraContrast(int contrast)
400 {
401  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
402  "CC %d\r", contrast) < CMUCAM4_CMD_BUFFER_SIZE)
403  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
405 }
406 
408 {
409  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
410  "CR %d\r", reg) < CMUCAM4_CMD_BUFFER_SIZE)
411  ? _intCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
413 }
414 
415 int CMUcam4::cameraRegisterWrite(int reg, int value, int mask)
416 {
417  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
418  "CW %d %d %d\r", reg, value, mask) < CMUCAM4_CMD_BUFFER_SIZE)
419  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
421 }
422 
423 /*******************************************************************************
424 * Camera Sensor Auto Control Commands
425 *******************************************************************************/
426 
428 {
429  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
430  "AG %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
431  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
433 }
434 
436 {
437  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
438  "AW %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
439  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
441 }
442 
443 /*******************************************************************************
444 * Camera Format Commands
445 *******************************************************************************/
446 
448 {
449  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
450  "HM %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
451  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
453 }
454 
455 int CMUcam4::verticalFlip(int active)
456 {
457  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
458  "VF %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
459  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
461 }
462 
463 /*******************************************************************************
464 * Camera Effect Commands
465 *******************************************************************************/
466 
468 {
469  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
470  "BW %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
471  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
473 }
474 
475 int CMUcam4::negativeMode(int active)
476 {
477  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
478  "NG %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
479  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
481 }
482 
483 /*******************************************************************************
484 * Auxiliary I/O Commands
485 *******************************************************************************/
486 
488 {
489  return _intCommandWrapper("GB\r", CMUCAM4_NON_FS_TIMEOUT);
490 }
491 
493 {
494  int errorValue; int resultValue; long returnValue;
495 
496  if(errorValue = _commandWrapper("GD\r", CMUCAM4_NON_FS_TIMEOUT))
497  {
498  return errorValue;
499  }
500 
501  if(errorValue = setjmp(_env))
502  {
503  return errorValue;
504  }
505 
506  _receiveData();
507  resultValue = (sscanf(_resBuffer, "%ld ", &returnValue) == 1);
508 
509  _waitForIdle();
510  return resultValue ? returnValue : CMUCAM4_UNEXPECTED_RESPONCE;
511 }
512 
514 {
515  return _intCommandWrapper("GP\r", CMUCAM4_NON_FS_TIMEOUT);
516 }
517 
519 {
520  return _intCommandWrapper("GR\r", CMUCAM4_NON_FS_TIMEOUT);
521 }
522 
524 {
525  return _intCommandWrapper("PI\r", CMUCAM4_NON_FS_TIMEOUT);
526 }
527 
528 int CMUcam4::panOutput(int direction, int output)
529 {
530  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
531  "PO %d %d\r", direction, output) < CMUCAM4_CMD_BUFFER_SIZE)
532  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
534 }
535 
537 {
538  return _intCommandWrapper("TI\r", CMUCAM4_NON_FS_TIMEOUT);
539 }
540 
541 int CMUcam4::tiltOutput(int direction, int output)
542 {
543  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
544  "TO %d %d\r", direction, output) < CMUCAM4_CMD_BUFFER_SIZE)
545  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
547 }
548 
550 {
551  return _intCommandWrapper("GI\r", CMUCAM4_NON_FS_TIMEOUT);
552 }
553 
554 int CMUcam4::setOutputs(int directions, int outputs)
555 {
556  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
557  "SO %d %d\r", directions, outputs) < CMUCAM4_CMD_BUFFER_SIZE)
558  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
560 }
561 
563 {
564  return _voidCommandWrapper("L0\r", CMUCAM4_NON_FS_TIMEOUT);
565 }
566 
567 int CMUcam4::LEDOn(long frequency)
568 {
569  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
570  "L1 %ld\r", frequency) < CMUCAM4_CMD_BUFFER_SIZE)
571  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
573 }
574 
575 /*******************************************************************************
576 * Servo Commands
577 *******************************************************************************/
578 
580 {
581  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
582  "GS %d\r", servo) < CMUCAM4_CMD_BUFFER_SIZE)
583  ? _intCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
585 }
586 
587 int CMUcam4::setServoPosition(int servo, int active, int pulseLength)
588 {
589  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
590  "SS %d %d %d\r", servo, active, pulseLength) < CMUCAM4_CMD_BUFFER_SIZE)
591  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
593 }
594 
595 int CMUcam4::automaticPan(int active, int reverse)
596 {
597  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
598  "AP %d %d\r", active, reverse) < CMUCAM4_CMD_BUFFER_SIZE)
599  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
601 }
602 
603 int CMUcam4::automaticTilt(int active, int reverse)
604 {
605  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
606  "AT %d %d\r", active, reverse) < CMUCAM4_CMD_BUFFER_SIZE)
607  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
609 }
610 
611 int CMUcam4::autoPanParameters(int proportionalGain, int derivativeGain)
612 {
613  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
614  "PP %d %d\r", proportionalGain, derivativeGain) < CMUCAM4_CMD_BUFFER_SIZE)
615  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
617 }
618 
619 int CMUcam4::autoTiltParameters(int proportionalGain, int derivativeGain)
620 {
621  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
622  "TP %d %d\r", proportionalGain, derivativeGain) < CMUCAM4_CMD_BUFFER_SIZE)
623  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
625 }
626 
627 /*******************************************************************************
628 * Television Commands
629 *******************************************************************************/
630 
632 {
633  return _voidCommandWrapper("M0\r", CMUCAM4_NON_FS_TIMEOUT);
634 }
635 
637 {
638  return _voidCommandWrapper("M1\r", CMUCAM4_NON_FS_TIMEOUT);
639 }
640 
641 int CMUcam4::monitorFreeze(int active)
642 {
643  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
644  "MF %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
645  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
647 }
648 
649 int CMUcam4::monitorSignal(int active)
650 {
651  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
652  "MS %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
653  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
655 }
656 
657 /*******************************************************************************
658 * Color Tracking Commands
659 *******************************************************************************/
660 
662 {
663  int errorValue; int resultValue;
664 
665  if(pointer == NULL)
666  {
667  return CMUCAM4_RETURN_FAILURE;
668  }
669 
670  if(errorValue = _commandWrapper("GT\r", CMUCAM4_NON_FS_TIMEOUT))
671  {
672  return errorValue;
673  }
674 
675  if(errorValue = setjmp(_env))
676  {
677  return errorValue;
678  }
679 
680  _receiveData();
681  resultValue = (sscanf(_resBuffer, "%d %d %d %d %d %d ",
682  &(pointer->redMin),
683  &(pointer->redMax),
684  &(pointer->greenMin),
685  &(pointer->greenMax),
686  &(pointer->blueMin),
687  &(pointer->blueMax)) == 6);
688 
689  _waitForIdle();
691 }
692 
694 {
695  int errorValue; int resultValue;
696 
697  if(pointer == NULL)
698  {
699  return CMUCAM4_RETURN_FAILURE;
700  }
701 
702  if(errorValue = _commandWrapper("GW\r", CMUCAM4_NON_FS_TIMEOUT))
703  {
704  return errorValue;
705  }
706 
707  if(errorValue = setjmp(_env))
708  {
709  return errorValue;
710  }
711 
712  _receiveData();
713  resultValue = (sscanf(_resBuffer, "%d %d %d %d ",
714  &(pointer->topLeftX),
715  &(pointer->topLeftY),
716  &(pointer->bottomRightX),
717  &(pointer->bottomRightY)) == 4);
718 
719  _waitForIdle();
721 }
722 
724 {
725  return _voidCommandWrapper("ST\r", CMUCAM4_NON_FS_TIMEOUT);
726 }
727 
728 int CMUcam4::setTrackingParameters(int redMin, int redMax,
729  int greenMin, int greenMax,
730  int blueMin, int blueMax)
731 {
732  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
733  "ST %d %d %d %d %d %d\r",
734  redMin, redMax, greenMin, greenMax, blueMin, blueMax)
735  < CMUCAM4_CMD_BUFFER_SIZE)
736  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
738 }
739 
741 {
742  return _voidCommandWrapper("SW\r", CMUCAM4_NON_FS_TIMEOUT);
743 }
744 
745 int CMUcam4::setTrackingWindow(int topLeftX, int topLeftY,
746  int bottomRightX, int bottomRightY)
747 {
748  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
749  "SW %d %d %d %d\r",
750  topLeftX, topLeftY, bottomRightX, bottomRightY)
751  < CMUCAM4_CMD_BUFFER_SIZE)
752  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
754 }
755 
757 {
758  int errorValue; static int resetTries; char cmdBuffer[CMUCAM4_IC_LENGTH];
759 
760  if(_state == DEACTIVATED)
761  {
762  return CMUCAM4_NOT_ACTIVATED;
763  }
764 
765  if(snprintf(cmdBuffer, CMUCAM4_IC_LENGTH,
766  CMUCAM4_IC_STRING, (_version / 100), (_version % 100))
767  >= CMUCAM4_IC_LENGTH)
768  {
770  }
771 
772  resetTries = CMUCAM4_IDLE_TRIES;
773  errorValue = setjmp(_env);
774 
775  if(resetTries-- <= 0)
776  {
777  return errorValue;
778  }
779 
780  _setReadTimeout(CMUCAM4_IDLE_TIMEOUT);
781  _com.write((uint8_t) '\0');
782  _com.write((uint8_t) '\0');
783  _com.write((uint8_t) '\0');
784  _com.write("\rGV\r");
785  _waitForString(cmdBuffer);
786 
787  return CMUCAM4_RETURN_SUCCESS;
788 }
789 
791 {
792  return _commandWrapper("TC\r", CMUCAM4_NON_FS_TIMEOUT);
793 }
794 
795 int CMUcam4::trackColor(int redMin, int redMax,
796  int greenMin, int greenMax,
797  int blueMin, int blueMax)
798 {
799  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
800  "TC %d %d %d %d %d %d\r",
801  redMin, redMax, greenMin, greenMax, blueMin, blueMax)
802  < CMUCAM4_CMD_BUFFER_SIZE)
803  ? _commandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
805 }
806 
807 int CMUcam4::trackWindow(int redRange, int greenRange, int blueRange)
808 {
809  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
810  "TW %d %d %d\r", redRange, greenRange, blueRange)
811  < CMUCAM4_CMD_BUFFER_SIZE)
812  ? _commandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
814 }
815 
816 int CMUcam4::getHistogram(int channel, int bins)
817 {
818  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
819  "GH %d %d\r", channel, bins)
820  < CMUCAM4_CMD_BUFFER_SIZE)
821  ? _commandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
823 }
824 
826 {
827  return _commandWrapper("GM\r", CMUCAM4_NON_FS_TIMEOUT);
828 }
829 
831 {
832  int errorValue;
833 
834  if(pointer == NULL)
835  {
836  return CMUCAM4_RETURN_FAILURE;
837  }
838 
839  if(errorValue = _responceWrapper('F'))
840  {
841  return errorValue;
842  }
843 
844  if(strcmp(_resBuffer, "F ") != 0)
845  {
847  }
848 
849  if(errorValue = setjmp(_env))
850  {
851  return errorValue;
852  }
853 
854  _readBinary(pointer->pixels, CMUCAM4_ID_T_LENGTH, CMUCAM4_ID_T_LENGTH, 0);
855 
856  return (_readWithTimeout() == '\r')
858 }
859 
861 {
862  int errorValue; char * buffer = (_resBuffer + sizeof('H')); size_t counter;
863 
864  if(pointer == NULL)
865  {
866  return CMUCAM4_RETURN_FAILURE;
867  }
868 
869  if(errorValue = _responceWrapper('H'))
870  {
871  return errorValue;
872  }
873 
874  for(counter = 0; counter < CMUCAM4_HD_1_T_LENGTH; counter++)
875  {
876  if((*buffer) == '\0')
877  {
879  }
880 
881  pointer->bins[counter] = ((uint8_t) strtol(buffer, &buffer, 10));
882  }
883 
884  if((*buffer) != '\0')
885  {
887  }
888 
889  return CMUCAM4_RETURN_SUCCESS;
890 }
891 
893 {
894  int errorValue; char * buffer = (_resBuffer + sizeof('H')); size_t counter;
895 
896  if(pointer == NULL)
897  {
898  return CMUCAM4_RETURN_FAILURE;
899  }
900 
901  if(errorValue = _responceWrapper('H'))
902  {
903  return errorValue;
904  }
905 
906  for(counter = 0; counter < CMUCAM4_HD_2_T_LENGTH; counter++)
907  {
908  if((*buffer) == '\0')
909  {
911  }
912 
913  pointer->bins[counter] = ((uint8_t) strtol(buffer, &buffer, 10));
914  }
915 
916  if((*buffer) != '\0')
917  {
919  }
920 
921  return CMUCAM4_RETURN_SUCCESS;
922 }
923 
925 {
926  int errorValue; char * buffer = (_resBuffer + sizeof('H')); size_t counter;
927 
928  if(pointer == NULL)
929  {
930  return CMUCAM4_RETURN_FAILURE;
931  }
932 
933  if(errorValue = _responceWrapper('H'))
934  {
935  return errorValue;
936  }
937 
938  for(counter = 0; counter < CMUCAM4_HD_4_T_LENGTH; counter++)
939  {
940  if((*buffer) == '\0')
941  {
943  }
944 
945  pointer->bins[counter] = ((uint8_t) strtol(buffer, &buffer, 10));
946  }
947 
948  if((*buffer) != '\0')
949  {
951  }
952 
953  return CMUCAM4_RETURN_SUCCESS;
954 }
955 
957 {
958  int errorValue; char * buffer = (_resBuffer + sizeof('H')); size_t counter;
959 
960  if(pointer == NULL)
961  {
962  return CMUCAM4_RETURN_FAILURE;
963  }
964 
965  if(errorValue = _responceWrapper('H'))
966  {
967  return errorValue;
968  }
969 
970  for(counter = 0; counter < CMUCAM4_HD_8_T_LENGTH; counter++)
971  {
972  if((*buffer) == '\0')
973  {
975  }
976 
977  pointer->bins[counter] = ((uint8_t) strtol(buffer, &buffer, 10));
978  }
979 
980  if((*buffer) != '\0')
981  {
983  }
984 
985  return CMUCAM4_RETURN_SUCCESS;
986 }
987 
989 {
990  int errorValue; char * buffer = (_resBuffer + sizeof('H')); size_t counter;
991 
992  if(pointer == NULL)
993  {
994  return CMUCAM4_RETURN_FAILURE;
995  }
996 
997  if(errorValue = _responceWrapper('H'))
998  {
999  return errorValue;
1000  }
1001 
1002  for(counter = 0; counter < CMUCAM4_HD_16_T_LENGTH; counter++)
1003  {
1004  if((*buffer) == '\0')
1005  {
1007  }
1008 
1009  pointer->bins[counter] = ((uint8_t) strtol(buffer, &buffer, 10));
1010  }
1011 
1012  if((*buffer) != '\0')
1013  {
1015  }
1016 
1017  return CMUCAM4_RETURN_SUCCESS;
1018 }
1019 
1021 {
1022  int errorValue; char * buffer = (_resBuffer + sizeof('H')); size_t counter;
1023 
1024  if(pointer == NULL)
1025  {
1026  return CMUCAM4_RETURN_FAILURE;
1027  }
1028 
1029  if(errorValue = _responceWrapper('H'))
1030  {
1031  return errorValue;
1032  }
1033 
1034  for(counter = 0; counter < CMUCAM4_HD_32_T_LENGTH; counter++)
1035  {
1036  if((*buffer) == '\0')
1037  {
1039  }
1040 
1041  pointer->bins[counter] = ((uint8_t) strtol(buffer, &buffer, 10));
1042  }
1043 
1044  if((*buffer) != '\0')
1045  {
1047  }
1048 
1049  return CMUCAM4_RETURN_SUCCESS;
1050 }
1051 
1053 {
1054  int errorValue; char * buffer = (_resBuffer + sizeof('H')); size_t counter;
1055 
1056  if(pointer == NULL)
1057  {
1058  return CMUCAM4_RETURN_FAILURE;
1059  }
1060 
1061  if(errorValue = _responceWrapper('H'))
1062  {
1063  return errorValue;
1064  }
1065 
1066  for(counter = 0; counter < CMUCAM4_HD_64_T_LENGTH; counter++)
1067  {
1068  if((*buffer) == '\0')
1069  {
1071  }
1072 
1073  pointer->bins[counter] = ((uint8_t) strtol(buffer, &buffer, 10));
1074  }
1075 
1076  if((*buffer) != '\0')
1077  {
1079  }
1080 
1081  return CMUCAM4_RETURN_SUCCESS;
1082 }
1083 
1085 {
1086  int errorValue;
1087 
1088  if(pointer == NULL)
1089  {
1090  return CMUCAM4_RETURN_FAILURE;
1091  }
1092 
1093  if(errorValue = _responceWrapper('S'))
1094  {
1095  return errorValue;
1096  }
1097 
1098  return (sscanf(_resBuffer,
1099  "S %d %d %d %d %d %d %d %d %d %d %d %d ",
1100  &(pointer->RMean),
1101  &(pointer->GMean),
1102  &(pointer->BMean),
1103  &(pointer->RMedian),
1104  &(pointer->GMedian),
1105  &(pointer->BMedian),
1106  &(pointer->RMode),
1107  &(pointer->GMode),
1108  &(pointer->BMode),
1109  &(pointer->RStDev),
1110  &(pointer->GStDev),
1111  &(pointer->BStDev)) == 12)
1113 }
1114 
1116 {
1117  int errorValue;
1118 
1119  if(pointer == NULL)
1120  {
1121  return CMUCAM4_RETURN_FAILURE;
1122  }
1123 
1124  if(errorValue = _responceWrapper('T'))
1125  {
1126  return errorValue;
1127  }
1128 
1129  return (sscanf(_resBuffer,
1130  "T %d %d %d %d %d %d %d %d ",
1131  &(pointer->mx),
1132  &(pointer->my),
1133  &(pointer->x1),
1134  &(pointer->y1),
1135  &(pointer->x2),
1136  &(pointer->y2),
1137  &(pointer->pixels),
1138  &(pointer->confidence)) == 8)
1140 }
1141 
1142 int CMUcam4::pollMode(int active)
1143 {
1144  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1145  "PM %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
1146  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
1148 }
1149 
1150 int CMUcam4::lineMode(int active)
1151 {
1152  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1153  "LM %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
1154  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
1156 }
1157 
1158 int CMUcam4::switchingMode(int active)
1159 {
1160  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1161  "SM %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
1162  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
1164 }
1165 
1166 int CMUcam4::testMode(int active)
1167 {
1168  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1169  "TM %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
1170  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
1172 }
1173 
1174 int CMUcam4::colorTracking(int active)
1175 {
1176  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1177  "CT %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
1178  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
1180 }
1181 
1183 {
1184  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1185  "HT %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
1186  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
1188 }
1189 
1191 {
1192  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1193  "IF %d\r", active) < CMUCAM4_CMD_BUFFER_SIZE)
1194  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
1196 }
1197 
1198 int CMUcam4::noiseFilter(int threshold)
1199 {
1200  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1201  "NF %d\r", threshold) < CMUCAM4_CMD_BUFFER_SIZE)
1202  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT)
1204 }
1205 
1206 /*******************************************************************************
1207 * File System Commands
1208 *******************************************************************************/
1209 
1210 int CMUcam4::changeAttributes(const char * fileOrDirectoryPathName,
1211  const char * attributes)
1212 {
1213  if((fileOrDirectoryPathName == NULL) || (attributes == NULL))
1214  {
1215  return CMUCAM4_RETURN_FAILURE;
1216  }
1217 
1218  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1219  "CA \"%s\" \"%s\"\r", fileOrDirectoryPathName, attributes)
1220  < CMUCAM4_CMD_BUFFER_SIZE)
1221  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_FS_TIMEOUT)
1223 }
1224 
1225 int CMUcam4::changeDirectory(const char * directoryPathAndName)
1226 {
1227  if(directoryPathAndName == NULL)
1228  {
1229  return CMUCAM4_RETURN_FAILURE;
1230  }
1231 
1232  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1233  "CD \"%s\"\r", directoryPathAndName)
1234  < CMUCAM4_CMD_BUFFER_SIZE)
1235  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_FS_TIMEOUT)
1237 }
1238 
1240 {
1241  int errorValue; int resultValue;
1242 
1243  if(pointer == NULL)
1244  {
1245  return CMUCAM4_RETURN_FAILURE;
1246  }
1247 
1248  if(errorValue = _commandWrapper("DI\r", CMUCAM4_FS_TIMEOUT))
1249  {
1250  return errorValue;
1251  }
1252 
1253  if(errorValue = setjmp(_env))
1254  {
1255  return errorValue;
1256  }
1257 
1258  _receiveData();
1259  memset(pointer->volumeLabel, '\0', CMUCAM4_VL_LENGTH + 1);
1260  memset(pointer->fileSystemType, '\0', CMUCAM4_FST_LENGTH + 1);
1261 
1262  resultValue = (sscanf(_resBuffer,
1263  "\"%" CMUCAM4_VL_LENGTH_STR "c\" "
1264  "\"%" CMUCAM4_FST_LENGTH_STR "c\" "
1265  "%lxh %lxh %lu %lu %lu %lu ",
1266  pointer->volumeLabel,
1267  pointer->fileSystemType,
1268  &(pointer->diskSignature),
1269  &(pointer->volumeIdentification),
1270  &(pointer->countOfDataSectors),
1271  &(pointer->bytesPerSector),
1272  &(pointer->sectorsPerCluster),
1273  &(pointer->countOfClusters)) == 8);
1274 
1275  _waitForIdle();
1276  return resultValue ? CMUCAM4_RETURN_SUCCESS : CMUCAM4_UNEXPECTED_RESPONCE;
1277 }
1278 
1280 {
1281  int errorValue; int resultValue;
1282 
1283  if(pointer == NULL)
1284  {
1285  return CMUCAM4_RETURN_FAILURE;
1286  }
1287 
1288  if(errorValue = _commandWrapper("DS\r", CMUCAM4_FS_TIMEOUT))
1289  {
1290  return errorValue;
1291  }
1292 
1293  if(errorValue = setjmp(_env))
1294  {
1295  return errorValue;
1296  }
1297 
1298  _receiveData();
1299 
1300  resultValue = (sscanf(_resBuffer,
1301  "%lu %lu ",
1302  &(pointer->freeSectorCount),
1303  &(pointer->usedSectorCount)) == 2);
1304 
1305  _waitForIdle();
1306  return resultValue ? CMUCAM4_RETURN_SUCCESS : CMUCAM4_UNEXPECTED_RESPONCE;
1307 }
1308 
1310 {
1311  return _voidCommandWrapper("FM\r", CMUCAM4_FS_TIMEOUT);
1312 }
1313 
1315  size_t size, unsigned long offset)
1316 {
1317  int errorValue; unsigned long directorySize;
1318 
1319  if(errorValue = _commandWrapper("LS\r", CMUCAM4_FS_TIMEOUT))
1320  {
1321  return errorValue;
1322  }
1323 
1324  if(errorValue = setjmp(_env))
1325  {
1326  return errorValue;
1327  }
1328 
1329  for(directorySize = 0; 1; directorySize++)
1330  {
1331  _receiveData();
1332 
1333  if((*_resBuffer) == ':')
1334  {
1335  break;
1336  }
1337 
1338  if((pointer != NULL) && (offset <= directorySize) &&
1339  ((directorySize - offset) < ((unsigned long) size)))
1340  {
1341  memset(pointer[directorySize - offset].name,
1342  '\0', CMUCAM4_NAME_LENGTH + 1);
1343  memset(pointer[directorySize - offset].attributes,
1344  '\0', CMUCAM4_ATTR_LENGTH + 1);
1345 
1346  if(sscanf(_resBuffer,
1347  " \"%" CMUCAM4_NAME_LENGTH_STR "c\" "
1348  "%" CMUCAM4_ATTR_LENGTH_STR "c ",
1349  pointer[directorySize - offset].name,
1350  pointer[directorySize - offset].attributes) != 2)
1351  {
1353  }
1354 
1355  pointer[directorySize - offset].size = 0;
1356 
1357  if(strchr(pointer[directorySize - offset].attributes, 'D') == NULL)
1358  {
1359  if(sscanf(_resBuffer,
1360  " \"%*" CMUCAM4_NAME_LENGTH_STR "c\" "
1361  "%*" CMUCAM4_ATTR_LENGTH_STR "c "
1362  "%lu ",
1363  &(pointer[directorySize - offset].size)) != 1)
1364  {
1366  }
1367  }
1368  }
1369  }
1370 
1371  return (long) directorySize; // Will be between 0 and 65,536 entries.
1372 }
1373 
1374 int CMUcam4::makeDirectory(const char * directoryPathAndName)
1375 {
1376  if(directoryPathAndName == NULL)
1377  {
1378  return CMUCAM4_RETURN_FAILURE;
1379  }
1380 
1381  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1382  "MK \"%s\"\r", directoryPathAndName)
1383  < CMUCAM4_CMD_BUFFER_SIZE)
1384  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_FS_TIMEOUT)
1386 }
1387 
1388 int CMUcam4::moveEntry(const char * oldEntryPathAndName,
1389  const char * newEntryPathAndName)
1390 {
1391  if((oldEntryPathAndName == NULL) || (newEntryPathAndName == NULL))
1392  {
1393  return CMUCAM4_RETURN_FAILURE;
1394  }
1395 
1396  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1397  "MV \"%s\" \"%s\"\r", oldEntryPathAndName, newEntryPathAndName)
1398  < CMUCAM4_CMD_BUFFER_SIZE)
1399  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_FS_TIMEOUT)
1401 }
1402 
1403 int CMUcam4::printLine(const char * filePathAndName, const char * textToAppend)
1404 {
1405  if((filePathAndName == NULL) || (textToAppend == NULL))
1406  {
1407  return CMUCAM4_RETURN_FAILURE;
1408  }
1409 
1410  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1411  "PL \"%s\" \"%s\"\r", filePathAndName, textToAppend)
1412  < CMUCAM4_CMD_BUFFER_SIZE)
1413  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_FS_TIMEOUT)
1415 }
1416 
1417 long CMUcam4::filePrint(const char * filePathAndName, uint8_t * buffer,
1418  size_t size, unsigned long offset)
1419 {
1420  int errorValue; unsigned long fileSize;
1421 
1422  if(filePathAndName == NULL)
1423  {
1424  return CMUCAM4_RETURN_FAILURE;
1425  }
1426 
1427  if(snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1428  "PR \"%s\"\r", filePathAndName) >= CMUCAM4_CMD_BUFFER_SIZE)
1429  {
1430  return CMUCAM4_COMMAND_OVERFLOW;
1431  }
1432 
1433  if(errorValue = _commandWrapper(_cmdBuffer, CMUCAM4_FS_TIMEOUT))
1434  {
1435  return errorValue;
1436  }
1437 
1438  if(errorValue = setjmp(_env))
1439  {
1440  return errorValue;
1441  }
1442 
1443  _receiveData();
1444 
1445  if(sscanf(_resBuffer, "%lu ", &fileSize) != 1)
1446  {
1448  }
1449 
1450  _readBinary(buffer, size, fileSize, offset);
1451 
1452  _waitForIdle();
1453  return (long) fileSize; // Will be between 0 and 2,147,483,647 bytes.
1454 }
1455 
1456 int CMUcam4::removeEntry(const char * fileOrDirectoryPathAndName)
1457 {
1458  if(fileOrDirectoryPathAndName == NULL)
1459  {
1460  return CMUCAM4_RETURN_FAILURE;
1461  }
1462 
1463  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1464  "RM \"%s\"\r", fileOrDirectoryPathAndName)
1465  < CMUCAM4_CMD_BUFFER_SIZE)
1466  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_FS_TIMEOUT)
1468 }
1469 
1471 {
1472  return _voidCommandWrapper("UM\r", CMUCAM4_FS_TIMEOUT);
1473 }
1474 
1475 /*******************************************************************************
1476 * Image Capture Commands
1477 *******************************************************************************/
1478 
1480 {
1481  return _voidCommandWrapper("DB\r", CMUCAM4_FS_TIMEOUT);
1482 }
1483 
1484 int CMUcam4::dumpFrame(int horizontalResolution, int verticalResolution)
1485 {
1486  return (snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1487  "DF %d %d\r", horizontalResolution, verticalResolution)
1488  < CMUCAM4_CMD_BUFFER_SIZE)
1489  ? _voidCommandWrapper(_cmdBuffer, CMUCAM4_FS_TIMEOUT)
1491 }
1492 
1494 {
1495  int errorValue;
1496 
1497  if(pointer == NULL)
1498  {
1499  return CMUCAM4_RETURN_FAILURE;
1500  }
1501 
1502  if(errorValue = _commandWrapper("SB\r", CMUCAM4_NON_FS_TIMEOUT))
1503  {
1504  return errorValue;
1505  }
1506 
1507  if(errorValue = setjmp(_env))
1508  {
1509  return errorValue;
1510  }
1511 
1512  _readBinary(pointer->pixels, CMUCAM4_ID_T_LENGTH, CMUCAM4_ID_T_LENGTH, 0);
1513 
1514  if(_readWithTimeout() != '\r')
1515  {
1517  }
1518 
1519  _waitForIdle();
1520  return CMUCAM4_RETURN_SUCCESS;
1521 }
1522 
1523 int CMUcam4::sendFrame(int horizontalResolution, int verticalResolution,
1524  uint16_t * buffer,
1525  size_t horizonalSize, size_t horizontalOffset,
1526  size_t verticalSize, size_t verticalOffset)
1527 {
1528  int errorValue; int serialBuffer0; int serialBuffer1;
1529  size_t indexX; size_t indexY; size_t resolutionX; size_t resolutionY;
1530 
1531  resolutionX = (CMUCAM4_FRAME_H_RES >> horizontalResolution);
1532  resolutionY = (CMUCAM4_FRAME_V_RES >> verticalResolution);
1533 
1534  if(snprintf(_cmdBuffer, CMUCAM4_CMD_BUFFER_SIZE,
1535  "SF %d %d\r", horizontalResolution, verticalResolution)
1536  >= CMUCAM4_CMD_BUFFER_SIZE)
1537  {
1538  return CMUCAM4_COMMAND_OVERFLOW;
1539  }
1540 
1541  if(errorValue = _commandWrapper(_cmdBuffer, CMUCAM4_NON_FS_TIMEOUT))
1542  {
1543  return errorValue;
1544  }
1545 
1546  if(errorValue = setjmp(_env))
1547  {
1548  return errorValue;
1549  }
1550 
1551  for(indexX = 0; indexX < resolutionX; indexX++)
1552  {
1553  _setReadTimeout(CMUCAM4_NON_FS_TIMEOUT);
1554 
1555  _receiveData();
1556 
1557  if((*_resBuffer) == ':')
1558  {
1560  }
1561 
1562  switch(_version)
1563  {
1564  case VERSION_100:
1565  case VERSION_101:
1566 
1567  if(strcmp(_resBuffer, "DAT:") != 0)
1568  {
1570  }
1571 
1572  break;
1573 
1574  case VERSION_102:
1575  case VERSION_103:
1576 
1577  if(strcmp(_resBuffer, "DAT: ") != 0)
1578  {
1580  }
1581 
1582  break;
1583  }
1584 
1585  for(indexY = 0; indexY < resolutionY; indexY++)
1586  {
1587  serialBuffer0 = _readWithTimeout();
1588  serialBuffer1 = _readWithTimeout();
1589 
1590  if((buffer != NULL) && (horizontalOffset <= indexX) &&
1591  ((indexX - horizontalOffset) < horizonalSize) &&
1592  (verticalOffset <= indexY) &&
1593  ((indexY - verticalOffset) < verticalSize))
1594  {
1595  buffer[((indexY - verticalOffset) * horizonalSize)
1596  + (indexX - horizontalOffset)]
1597  = ((uint16_t) (serialBuffer0 | (serialBuffer1 << 8)));
1598  }
1599  }
1600 
1601  if(_readWithTimeout() != '\r')
1602  {
1604  }
1605  }
1606 
1607  _waitForIdle();
1608  return CMUCAM4_RETURN_SUCCESS;
1609 }
1610 
1611 /*******************************************************************************
1612 * Private Functions
1613 *******************************************************************************/
1614 
1615 int CMUcam4::_voidCommandWrapper(const char * command, unsigned long timeout)
1616 {
1617  int errorValue;
1618 
1619  if(errorValue = _commandWrapper(command, timeout))
1620  {
1621  return errorValue;
1622  }
1623 
1624  if(errorValue = setjmp(_env))
1625  {
1626  return errorValue;
1627  }
1628 
1629  _waitForIdle();
1630  return CMUCAM4_RETURN_SUCCESS;
1631 }
1632 
1633 int CMUcam4::_intCommandWrapper(const char * command, unsigned long timeout)
1634 {
1635  int errorValue; int resultValue; int returnValue;
1636 
1637  if(errorValue = _commandWrapper(command, timeout))
1638  {
1639  return errorValue;
1640  }
1641 
1642  if(errorValue = setjmp(_env))
1643  {
1644  return errorValue;
1645  }
1646 
1647  _receiveData();
1648  resultValue = (sscanf(_resBuffer, "%d ", &returnValue) == 1);
1649 
1650  _waitForIdle();
1651  return resultValue ? returnValue : CMUCAM4_UNEXPECTED_RESPONCE;
1652 }
1653 
1654 int CMUcam4::_commandWrapper(const char * command, unsigned long timeout)
1655 {
1656  int errorValue;
1657 
1658  if(errorValue = idleCamera())
1659  {
1660  return errorValue;
1661  }
1662 
1663  if(errorValue = setjmp(_env))
1664  {
1665  return errorValue;
1666  }
1667 
1668  _setReadTimeout(timeout);
1669  _com.write(command);
1670  _waitForResponce();
1671 
1672  return CMUCAM4_RETURN_SUCCESS;
1673 }
1674 
1675 int CMUcam4::_responceWrapper(char responce)
1676 {
1677  int errorValue;
1678 
1679  if(_state == DEACTIVATED)
1680  {
1681  return CMUCAM4_NOT_ACTIVATED;
1682  }
1683 
1684  if(errorValue = setjmp(_env))
1685  {
1686  return errorValue;
1687  }
1688 
1689  _setReadTimeout(CMUCAM4_NON_FS_TIMEOUT);
1690 
1691  for(;;)
1692  {
1693  _receiveData();
1694 
1695  if((*_resBuffer) == responce)
1696  {
1697  break;
1698  }
1699 
1700  if((*_resBuffer) == ':')
1701  {
1702  return CMUCAM4_STREAM_END;
1703  }
1704 
1705  if(strcmp(_resBuffer, "F ") == 0)
1706  {
1707  _readBinary(NULL, 0, CMUCAM4_ID_T_LENGTH, 0);
1708 
1709  if(_readWithTimeout() != '\r')
1710  {
1712  }
1713  }
1714  }
1715 
1716  return CMUCAM4_RETURN_SUCCESS;
1717 }
1718 
1719 void CMUcam4::_waitForIdle()
1720 {
1721  for(;;)
1722  {
1723  _readText();
1724 
1725  if(_startsWithString("MSG"))
1726  {
1727  continue; // Throw the message away.
1728  }
1729 
1730  _handleError();
1731 
1732  if((*_resBuffer) != ':')
1733  {
1734  longjmp(_env, CMUCAM4_UNEXPECTED_RESPONCE);
1735  }
1736 
1737  break;
1738  }
1739 }
1740 
1741 void CMUcam4::_waitForResponce()
1742 {
1743  _readText();
1744 
1745  if(strcmp(_resBuffer, "NCK") == 0)
1746  {
1747  _readText();
1748 
1749  if((*_resBuffer) == ':')
1750  {
1751  longjmp(_env, CMUCAM4_NCK_RESPONCE);
1752  }
1753 
1754  longjmp(_env, CMUCAM4_UNEXPECTED_RESPONCE);
1755  }
1756 
1757  if(strcmp(_resBuffer, "ACK") != 0)
1758  {
1759  longjmp(_env, CMUCAM4_UNEXPECTED_RESPONCE);
1760  }
1761 }
1762 
1763 void CMUcam4::_receiveData()
1764 {
1765  for(;;)
1766  {
1767  _readText();
1768 
1769  if(_startsWithString("MSG"))
1770  {
1771  continue; // Throw the message away.
1772  }
1773 
1774  _handleError();
1775 
1776  break;
1777  }
1778 }
1779 
1780 void CMUcam4::_handleError()
1781 {
1782  int errorValue; int sum; size_t index; size_t length;
1783 
1784  if(_startsWithString("ERR"))
1785  {
1786  sum = 0; length = strlen(_resBuffer);
1787 
1788  for(index = 0; index < length; index++)
1789  {
1790  sum += _resBuffer[index];
1791  }
1792 
1793  switch(sum)
1794  {
1795  case CMUCAM4_CAMERA_TIMEOUT_ERROR_SUM:
1796  errorValue = CMUCAM4_CAMERA_TIMEOUT_ERROR; break;
1797 
1798  case CMUCAM4_CAMERA_CONNECTION_ERROR_SUM:
1799  errorValue = CMUCAM4_CAMERA_CONNECTION_ERROR; break;
1800 
1801  case CMUCAM4_DISK_IO_ERROR_SUM:
1802  errorValue = CMUCAM4_DISK_IO_ERROR; break;
1803 
1804  case CMUCAM4_FILE_SYSTEM_CORRUPTED_SUM:
1805  errorValue = CMUCAM4_FILE_SYSTEM_CORRUPTED; break;
1806 
1807  case CMUCAM4_FILE_SYSTEM_UNSUPPORTED_SUM:
1808  errorValue = CMUCAM4_FILE_SYSTEM_UNSUPPORTED; break;
1809 
1810  case CMUCAM4_CARD_NOT_DETECTED_SUM:
1811  errorValue = CMUCAM4_CARD_NOT_DETECTED; break;
1812 
1813  case CMUCAM4_DISK_MAY_BE_FULL_SUM:
1814  errorValue = CMUCAM4_DISK_MAY_BE_FULL; break;
1815 
1816  case CMUCAM4_DIRECTORY_FULL_SUM:
1817  errorValue = CMUCAM4_DIRECTORY_FULL; break;
1818 
1819  case CMUCAM4_EXPECTED_AN_ENTRY_SUM:
1820  errorValue = CMUCAM4_EXPECTED_AN_ENTRY; break;
1821 
1822  case CMUCAM4_EXPECTED_A_DIRECTORY_SUM:
1823  errorValue = CMUCAM4_EXPECTED_A_DIRECTORY; break;
1824 
1825  case CMUCAM4_ENTRY_NOT_ACCESSIBLE_SUM:
1826  errorValue = CMUCAM4_ENTRY_NOT_ACCESSIBLE; break;
1827 
1828  case CMUCAM4_ENTRY_NOT_MODIFIABLE_SUM:
1829  errorValue = CMUCAM4_ENTRY_NOT_MODIFIABLE; break;
1830 
1831  case CMUCAM4_ENTRY_NOT_FOUND_SUM:
1832  errorValue = CMUCAM4_ENTRY_NOT_FOUND; break;
1833 
1834  // For v1.02 firmware and above.
1835  case CMUCAM4_ENTRY_ALREADY_EXISTS_SUM:
1836  errorValue = CMUCAM4_ENTRY_ALREADY_EXISTS; break;
1837 
1838  // For v1.01 firmware and below.
1839  case (CMUCAM4_ENTRY_ALREADY_EXISTS_SUM - 's'):
1840  errorValue = CMUCAM4_ENTRY_ALREADY_EXISTS; break;
1841 
1842  case CMUCAM4_DIRECTORY_LINK_MISSING_SUM:
1843  errorValue = CMUCAM4_DIRECTORY_LINK_MISSING; break;
1844 
1845  case CMUCAM4_DIRECTORY_NOT_EMPTY_SUM:
1846  errorValue = CMUCAM4_DIRECTORY_NOT_EMPTY; break;
1847 
1848  case CMUCAM4_NOT_A_DIRECTORY_SUM:
1849  errorValue = CMUCAM4_NOT_A_DIRECTORY; break;
1850 
1851  case CMUCAM4_NOT_A_FILE_SUM:
1852  errorValue = CMUCAM4_NOT_A_FILE; break;
1853 
1854  default:
1855  errorValue = CMUCAM4_UNEXPECTED_RESPONCE; break;
1856  }
1857 
1858  _readText();
1859 
1860  if((*_resBuffer) == ':')
1861  {
1862  longjmp(_env, errorValue);
1863  }
1864 
1865  longjmp(_env, CMUCAM4_UNEXPECTED_RESPONCE);
1866  }
1867 }
1868 
1869 void CMUcam4::_waitForString(const char * string)
1870 {
1871  size_t index; size_t length = strlen(string);
1872  memset(_resBuffer, '\0', CMUCAM4_RES_BUFFER_SIZE);
1873 
1874  do
1875  {
1876  for(index = 1; index < length; index++)
1877  {
1878  _resBuffer[index - 1] = _resBuffer[index];
1879  }
1880 
1881  _resBuffer[length - 1] = _readWithTimeout();
1882  }
1883  while(strcmp(_resBuffer, string) != 0);
1884 }
1885 
1886 int CMUcam4::_startsWithString(const char * string)
1887 {
1888  return (strncmp(_resBuffer, string, strlen(string)) == 0);
1889 }
1890 
1891 void CMUcam4::_readBinary(uint8_t * buffer, size_t size,
1892  unsigned long packetSize,
1893  unsigned long packetOffset)
1894 {
1895  int serialBuffer; unsigned long serialCounter;
1896 
1897  for(serialCounter = 0; serialCounter < packetSize; serialCounter++)
1898  {
1899  serialBuffer = _readWithTimeout();
1900 
1901  if((buffer != NULL) && (packetOffset <= serialCounter) &&
1902  ((serialCounter - packetOffset) < ((unsigned long) size)))
1903  {
1904  buffer[serialCounter - packetOffset] = ((uint8_t) serialBuffer);
1905  }
1906  }
1907 }
1908 
1909 void CMUcam4::_readText()
1910 {
1911  int serialBuffer; size_t serialCounter = 0;
1912  memset(_resBuffer, '\0', CMUCAM4_RES_BUFFER_SIZE);
1913 
1914  for(;;)
1915  {
1916  serialBuffer = _readWithTimeout();
1917 
1918  if(serialBuffer == '\r')
1919  {
1920  break;
1921  }
1922 
1923  _resBuffer[serialCounter++] = serialBuffer;
1924 
1925  if(serialCounter >= CMUCAM4_RES_BUFFER_SIZE)
1926  {
1927  longjmp(_env, CMUCAM4_RESPONCE_OVERFLOW);
1928  }
1929 
1930  switch(serialCounter)
1931  {
1932  case sizeof(':'):
1933 
1934  if((*_resBuffer) == ':')
1935  {
1936  return; // Found the idle character.
1937  }
1938 
1939  break;
1940 
1941  case (sizeof("F ") - 1):
1942 
1943  if(strcmp(_resBuffer, "F ") == 0)
1944  {
1945  return; // Found type F packet.
1946  }
1947 
1948  break;
1949 
1950  case (sizeof("DAT:") - 1):
1951 
1952  if(_state == ACTIVATED)
1953  {
1954  switch(_version)
1955  {
1956  case VERSION_100:
1957  case VERSION_101:
1958 
1959  if(strcmp(_resBuffer, "DAT:") == 0)
1960  {
1961  return; // Found a old style DAT packet.
1962  }
1963 
1964  break;
1965 
1966  case VERSION_102:
1967  case VERSION_103:
1968 
1969  break;
1970  }
1971  }
1972 
1973  break;
1974 
1975  case (sizeof("DAT: ") - 1):
1976 
1977  if(_state == ACTIVATED)
1978  {
1979  switch(_version)
1980  {
1981  case VERSION_100:
1982  case VERSION_101:
1983 
1984  break;
1985 
1986  case VERSION_102:
1987  case VERSION_103:
1988 
1989  if(strcmp(_resBuffer, "DAT: ") == 0)
1990  {
1991  return; // Found a new style DAT packet.
1992  }
1993 
1994  break;
1995  }
1996  }
1997 
1998  break;
1999 
2000  default: break;
2001  }
2002  }
2003 }
2004 
2005 void CMUcam4::_setReadTimeout(unsigned long timeout)
2006 {
2007  _timeout = timeout;
2008  _milliseconds = _com.milliseconds();
2009 }
2010 
2011 int CMUcam4::_readWithTimeout()
2012 {
2013  do
2014  {
2015  if((_com.milliseconds() - _milliseconds) >= _timeout)
2016  {
2017  longjmp(_env, CMUCAM4_SERIAL_TIMEOUT);
2018  }
2019  }
2020  while(_com.available() == 0);
2021 
2022  return _com.read();
2023 }
2024 
2025 /***************************************************************************//**
2026 * @file
2027 * @par MIT License - TERMS OF USE:
2028 * @n Permission is hereby granted, free of charge, to any person obtaining a
2029 * copy of this software and associated documentation files (the "Software"), to
2030 * deal in the Software without restriction, including without limitation the
2031 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
2032 * sell copies of the Software, and to permit persons to whom the Software is
2033 * furnished to do so, subject to the following conditions:
2034 * @n
2035 * @n The above copyright notice and this permission notice shall be included in
2036 * all copies or substantial portions of the Software.
2037 * @n
2038 * @n THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2039 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2040 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2041 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2042 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2043 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2044 * SOFTWARE.
2045 *******************************************************************************/