Remove whitespace, update email addresses and URLs.
[kodak.git] / dc210camera.cpp
1 //+----------------------------------------------------------------------------
2 //
3 // File:     kodak.cpp
4 //
5 // Module:
6 //
7 // Synopsis:
8 //
9 // Copyright (C) 1999-2000 Scott Gasch <[email protected]>
10 //
11 // Created:  12 Jan 2000
12 //
13 //+----------------------------------------------------------------------------
14
15 #include <stdlib.h>
16 #include <string.h>
17 #include <unistd.h>
18 #include <time.h>
19
20 #include "global.h"
21 #include "trace.h"
22 #include "debug.h"
23 #include "utils.h"
24 #include "dc210camera.h"
25
26
27 //+----------------------------------------------------------------------------
28 //
29 // Function:  CKodakDC210
30 //
31 // Synopsis:
32 //
33 // Arguments: void
34 //
35 // Returns:   void
36 //
37 // History:   sgasch Created Header    13 Jan 2000
38 //
39 //+----------------------------------------------------------------------------
40 CKodakDC210::CKodakDC210(char *szDevice, int iSpeed)
41 {
42         _fInitialized = false;
43         _pSerialPort = NULL;
44         _iMaxAttempts = 5;
45
46         //
47         // Open the serial port.
48         //
49         if (NULL == (_pSerialPort = new CSerialPort(szDevice)))
50         {
51                 Trace("CKodakDC210: unable to open serial port, aborting.");
52                 return;
53         }
54         Trace("Port opened.\n");
55
56         //
57         // Send the initialize command.
58         //
59         if (!Initialize())
60         {
61                 Trace("KodakDC210: unable to initialize camera communications, "
62                           "aborting.\n");
63                 return;
64         }
65         Trace("Camera initialized.\n");
66
67         //
68         // Set communications speed.
69         //
70         if (9600 != iSpeed)
71         {
72                 if (!SetSpeed(g_iSpeed))
73                 {
74                         Trace("InitiailzeCamera: Can't set baud rate.\n");
75                         ASSERT(false);
76                 }
77         }
78         Trace("Speed set.\n");
79
80         //
81         // Request a dump of properties.
82         //
83         if (!RefreshProperties())
84         {
85                 Trace("Unable to get properties of camera.\n");
86                 ASSERT(FALSE);
87         }
88         Trace("Properties received.\n");
89         
90         _fInitialized = true;
91 }
92
93
94 //+----------------------------------------------------------------------------
95 //
96 // Function:  ~CKodakDC210
97 //
98 // Synopsis:
99 //
100 // Arguments: void
101 //
102 // Returns:   void
103 //
104 // History:   sgasch Created Header    13 Jan 2000
105 //
106 //+----------------------------------------------------------------------------
107 CKodakDC210::~CKodakDC210(void)
108 {
109         //
110         // Reset camera and serial port speed to default of 9600 bps.
111         //
112         if (!SetSpeed(9600))
113         {
114                 Trace("~CKodakDC210: Can't reset the baud rate to 9600.");
115         }
116
117         //
118         // Close the serial port.
119         //
120         if (_pSerialPort)
121         {
122                 delete _pSerialPort;
123         }
124
125         _fInitialized = false;
126 }
127
128
129 //+----------------------------------------------------------------------------
130 //
131 // Function:  Initialize
132 //
133 // Synopsis:
134 //
135 // Arguments: void
136 //
137 // Returns:   bool
138 //
139 // History:   sgasch Created Header    13 Jan 2000
140 //
141 //+----------------------------------------------------------------------------
142 bool CKodakDC210::Initialize(void)
143 {
144         //
145         // The "initialize" command really causes the camera to query battery
146         // status but we send something here just to see if we can talk to the
147         // camera and fail if not.  Also if the camera is asleep this will wake
148         // it up.
149         //
150         if (!SendCommand(DC210_INITIALIZE, 0, 0, 0, 0))
151         {
152                 Trace("Initialize: Initialize command failed -- camera could be "
153                           "asleep.  Waiting 10 sec and retrying communications.\n");
154
155                 usleep(100);
156                 SetSpeed(9600);
157
158                 //
159                 // According to the host interface spec the camera needs at most
160                 // ten seconds to wake up and be ready to process more commands.
161                 //
162                 sleep(10);
163                 if (!SendCommand(DC210_INITIALIZE, 0, 0, 0, 0))
164                 {
165                         Trace("Initialize: Second try failed too, assuming bad "
166                                   "connection.\n");
167                         return(false);
168                 }
169         }
170         
171     //
172         // Like all commands, the DC210 returns a command-compete status code
173         // to notify you when it's done.  If it can't send a command-complete
174         // code within three seconds it will send a busy code.
175         //
176         if (!CommandComplete())
177         {
178                 Trace("Initialize: Never received command complete signal.\n");
179                 ASSERT(false);
180                 return(false);
181         }
182
183         //
184         // Success
185         //
186         return(true);
187 }
188
189
190 //+----------------------------------------------------------------------------
191 //
192 // Function:  SetSpeed
193 //
194 // Synopsis:
195 //
196 // Arguments: int iBps
197 //
198 // Returns:   bool
199 //
200 // History:   sgasch Created Header    13 Jan 2000
201 //
202 //+----------------------------------------------------------------------------
203 bool CKodakDC210::SetSpeed(int iBps)
204 {
205         BYTE bArg1, bArg2;
206
207         //
208         // Determine what arguments to send to the camera to communicate
209         // the new speed.
210         //
211         switch (iBps)
212         {
213                 case 9600:
214                         bArg1 = 0x96;
215                         bArg2 = 00;
216                         break;
217                 case 19200:
218                         bArg1 = 0x19;
219                         bArg2 = 0x20;
220                         break;
221                 case 38400:
222                         bArg1 = 0x38;
223                         bArg2 = 0x40;
224                         break;
225                 case 57600:
226                         bArg1 = 0x57;
227                         bArg2 = 0x60;
228                         break;
229                 case 115200:
230                         bArg1 = 0x11;
231                         bArg2 = 0x52;
232                         break;
233                 default:
234                         Trace("SetSpeed: illegal speed.\n");
235                         return(false);
236         }
237
238         //
239         // Send the command to the camera.  There will be no response to this
240         // command...
241         //
242         if (!SendCommand(DC210_SET_SPEED, bArg1, bArg2, 0, 0))
243         {
244                 Trace("SetSpeed: Camera communication error, speed not changed.\n");
245                 return(false);
246         }
247
248         //
249         // Sleep for a little while to let the camera switch speeds.
250         //
251         usleep(50);
252
253         //
254         // Change the rate at the serial port.
255         //
256         if (!_pSerialPort->SetBaudrate(iBps))
257         {
258                 Trace("SetSpeed: error switching serial port to new speed?\n");
259                 return(false);
260         }
261
262         //
263         // Sleep again to be sure everythign is done before another command
264         // can execute.
265         //
266         usleep(150);
267
268         //
269         // Success
270         //
271         return(true);
272 }
273
274
275 //+----------------------------------------------------------------------------
276 //
277 // Function:  TakePicture
278 //
279 // Synopsis:
280 //
281 // Arguments: void
282 //
283 // Returns:   bool
284 //
285 // History:   sgasch Created Header    13 Jan 2000
286 //
287 //+----------------------------------------------------------------------------
288 bool CKodakDC210::TakePicture(void)
289 {
290         //
291         // Precondition: we are initialized.
292         //
293         ASSERT(_fInitialized == true);
294
295         //
296         // Send the command to the camera.
297         //
298         if (!SendCommand(DC210_TAKE_PICTURE, 0, 0, 0, 0))
299         {
300                 Trace("TakePicture: Failed to send command.\n");
301                 return(false);
302         }
303
304         //
305         // Wait for the camera's command complete code.
306         //
307         if (!CommandComplete())
308         {
309                 Trace("TakePicture: Did not receive command completion signal.\n");
310                 return(false);
311         }
312
313         //
314         // Success
315         //
316         return(true);
317 }
318
319
320 //+----------------------------------------------------------------------------
321 //
322 // Function:  RefreshProperties
323 //
324 // Synopsis:
325 //
326 // Arguments: void
327 //
328 // Returns:   bool - true if command successful
329 //
330 // History:   sgasch Created Header    8 Jun 1999
331 //
332 //+----------------------------------------------------------------------------
333 bool CKodakDC210::RefreshProperties(void)
334 {
335         //
336         // We do _not_ assert that we are initialized here because this routine
337         // gets called in the constructor before we are initialized fully as
338         // part of class startup.
339         //
340
341         //
342         // Send the command to the camera.
343         //
344         if (!SendCommand(DC210_STATUS, 0, 0, 0, 0))
345         {
346                 Trace("RefreshProperties: Failed to send command.\n");
347                 return(false);
348         }
349         
350         //
351         // Immediately after the ACK byte from the camera (which SendCommand
352         // checks for) the camera will send us a 256 byte buffer (actually
353         // one packet control byte, 256 data bytes and one checksum byte for
354         // a total of 258 bytes on the serial line)  This buffer is the one
355         // with all the status data in it.
356         //
357         if (!ReadPacket(_bRawStatusData, 256))
358         {
359                 Trace("RefreshProperties: Did not get expected status buffer packet "
360                           "back.\n");
361                 return(false);
362         }
363
364         //
365         // After the buffer we get the usual command complete signal.
366         //
367         if (!CommandComplete())
368         {
369                 Trace("RefreshProperties: Did not get command completion signal.\n");
370                 return(false);
371         }
372
373         //
374         // Success
375         //
376         return(true);
377 }
378
379 //+----------------------------------------------------------------------------
380 //
381 // Function:  GetRawStatusData
382 //
383 // Synopsis:
384 //
385 // Arguments: BYTE *pData
386 //
387 // Returns:   bool
388 //
389 // History:   sgasch Created Header    13 Jan 2000
390 //
391 //+----------------------------------------------------------------------------
392 bool CKodakDC210::GetRawStatusData(BYTE *pData)
393 {
394         if (RefreshProperties())
395         {
396                 memcpy(pData, _bRawStatusData, 256);
397                 return(true);
398         }
399         return(false);
400 }
401
402
403 //+----------------------------------------------------------------------------
404 //
405 // Function:  GetFirmwareVersion
406 //
407 // Synopsis:
408 //
409 // Arguments: int *piMajor,
410 //            int *piMinor
411 //
412 // Returns:   bool
413 //
414 // History:   sgasch Created Header    13 Jan 2000
415 //
416 //+----------------------------------------------------------------------------
417 bool CKodakDC210::GetFirmwareVersion(int *piMajor, int *piMinor)
418 {
419         *piMajor = _bRawStatusData[2];
420         *piMinor = _bRawStatusData[3];
421         return(true);
422 }
423
424
425 //+----------------------------------------------------------------------------
426 //
427 // Function:  GetRomVersion
428 //
429 // Synopsis:
430 //
431 // Arguments: int *piMajor,
432 //            int *piMinor
433 //
434 // Returns:   bool
435 //
436 // History:   sgasch Created Header    13 Jan 2000
437 //
438 //+----------------------------------------------------------------------------
439 bool CKodakDC210::GetRomVersion(int *piMajor, int *piMinor)
440 {
441         *piMajor = _bRawStatusData[4];
442         *piMinor = _bRawStatusData[5];
443         return(true);
444 }
445
446
447 //+----------------------------------------------------------------------------
448 //
449 // Function:  GetBatteryStatus
450 //
451 // Synopsis:
452 //
453 // Arguments: DC210_BATTERY_STATE *pState
454 //
455 // Returns:   bool
456 //
457 // History:   sgasch Created Header    13 Jan 2000
458 //
459 //+----------------------------------------------------------------------------
460 bool CKodakDC210::GetBatteryStatus(DC210_BATTERY_STATE *pState)
461 {
462         switch(_bRawStatusData[8])
463         {
464             case 0:
465                         *pState = battery_full;
466                         break;
467             case 1:
468                         *pState = battery_low;
469                         break;
470             case 2:
471                         *pState = battery_empty;
472                         break;
473             default:
474                         ASSERT(false);
475                         *pState = battery_unknown;
476                         return(false);
477         }
478         return(true);
479 }
480
481
482 //+----------------------------------------------------------------------------
483 //
484 // Function:  IsAdapterAttached
485 //
486 // Synopsis:
487 //
488 // Arguments: bool *pfAttached
489 //
490 // Returns:   bool
491 //
492 // History:   sgasch Created Header    13 Jan 2000
493 //
494 //+----------------------------------------------------------------------------
495 bool CKodakDC210::IsAdapterAttached(bool *pfAttached)
496 {
497         if (RefreshProperties())
498         {
499                 if (_bRawStatusData[9])
500                 {
501                         *pfAttached = true;
502                 }
503                 else
504                 {
505                         *pfAttached = false;
506                 }
507                 return(true);
508         }
509         return(false);
510 }
511
512
513 //+----------------------------------------------------------------------------
514 //
515 // Function:  GetZoomState
516 //
517 // Synopsis:
518 //
519 // Arguments: DC210_ZOOM_STATE *pZoom
520 //
521 // Returns:   bool
522 //
523 // History:   sgasch Created Header    13 Jan 2000
524 //
525 //+----------------------------------------------------------------------------
526 bool CKodakDC210::GetZoomState(DC210_ZOOM_STATE *pZoom)
527 {
528         if (RefreshProperties())
529         {
530                 switch(_bRawStatusData[16] & 0x0F)
531                 {
532                 case 0:
533                                 *pZoom = zoom_fully_zoomed;
534                                 break;
535                 case 1:
536                                 *pZoom = zoom_3;
537                                 break;
538                 case 2:
539                                 *pZoom = zoom_2;
540                                 break;
541                 case 3:
542                                 *pZoom = zoom_1;
543                                 break;
544                 case 4:
545                                 *pZoom = zoom_wideangle;
546                                 break;
547                 case 5:
548                                 *pZoom = zoom_closeup;
549                                 break;
550                 default:
551                                 ASSERT(false);
552                                 *pZoom = zoom_unknown;
553                                 return(false);
554                 }
555                 return(true);
556         }
557         return(false);
558 }
559
560
561 //+----------------------------------------------------------------------------
562 //
563 // Function:  GetResolution
564 //
565 // Synopsis:
566 //
567 // Arguments: int *piWidth,
568 //            int *piHeight
569 //
570 // Returns:   bool
571 //
572 // History:   sgasch Created Header    13 Jan 2000
573 //
574 //+----------------------------------------------------------------------------
575 bool CKodakDC210::GetResolution(int *piWidth, int *piHeight)
576 {
577         if (0 == _bRawStatusData[22])
578         {
579                 *piWidth = 640;
580                 *piHeight = 480;
581         }
582         else if (1 == _bRawStatusData[22])
583         {
584                 *piWidth = 1152;
585                 *piHeight = 864;
586         }
587         else
588         {
589                 ASSERT(false);
590                 return(false);
591         }
592         return(true);
593 }
594
595 //+----------------------------------------------------------------------------
596 //
597 // Function:  IsFlashCharged
598 //
599 // Synopsis:
600 //
601 // Arguments: bool *pfCharged
602 //
603 // Returns:   bool
604 //
605 // History:   sgasch Created Header    13 Jan 2000
606 //
607 //+----------------------------------------------------------------------------
608 bool CKodakDC210::IsFlashCharged(bool *pfCharged)
609 {
610         if (RefreshProperties())
611         {
612                 if (_bRawStatusData[18])
613                 {
614                         *pfCharged = true;
615                 }
616                 else
617                 {
618                         *pfCharged = false;
619                 }
620                 return(true);
621         }
622         return(false);
623 }
624
625
626 //+----------------------------------------------------------------------------
627 //
628 // Function:  GetFlashState
629 //
630 // Synopsis:
631 //
632 // Arguments: DC210_FLASH_STATE *pState
633 //
634 // Returns:   bool
635 //
636 // History:   sgasch Created Header    13 Jan 2000
637 //
638 //+----------------------------------------------------------------------------
639 bool CKodakDC210::GetFlashState(DC210_FLASH_STATE *pState)
640 {
641         switch (_bRawStatusData[20])
642         {
643             case 0:
644                         *pState = flash_auto;
645                         break;
646             case 1:
647                         *pState = flash_fill;
648                         break;
649             case 2:
650                         *pState = flash_off;
651                         break;
652             case 3:
653                         *pState = flash_auto_redeye;
654                         break;
655             case 4:
656                         *pState = flash_fill_redeye;
657                         break;
658             default:
659                         ASSERT(false);
660                         *pState = flash_unknown;
661                         return(false);
662         }
663         return(true);
664 }
665
666
667 //+----------------------------------------------------------------------------
668 //
669 // Function:  GetCompressionState
670 //
671 // Synopsis:
672 //
673 // Arguments: DC210_COMPRESSION_STATE *pState
674 //
675 // Returns:   bool
676 //
677 // History:   sgasch Created Header    13 Jan 2000
678 //
679 //+----------------------------------------------------------------------------
680 bool CKodakDC210::GetCompressionState(DC210_COMPRESSION_STATE *pState)
681 {
682         switch (_bRawStatusData[19])
683         {
684             case 0:
685                         *pState = compression_none;
686                         break;
687             case 1:
688                         *pState = compression_low;
689                         break;
690             case 2:
691                         *pState = compression_medium;
692                         break;
693             case 3:
694                         *pState = compression_high;
695                         break;
696             default:
697                         ASSERT(false);
698                         *pState = compression_unknown;
699                         return(false);
700         }
701         return(true);
702 }
703
704
705 //+----------------------------------------------------------------------------
706 //
707 // Function:  GetPictureFormat
708 //
709 // Synopsis:
710 //
711 // Arguments: DC210_FILE_FORMAT *eFormat
712 //
713 // Returns:   bool
714 //
715 // History:   sgasch Created Header    13 Jan 2000
716 //
717 //+----------------------------------------------------------------------------
718 bool CKodakDC210::GetPictureFormat(DC210_FILE_FORMAT *eFormat)
719 {
720         if (2 == _bRawStatusData[23])
721         {
722                 *eFormat = format_raw;
723         }
724         else if (3 == _bRawStatusData[23])
725         {
726                 *eFormat = format_jpeg;
727         }
728         else if (4 == _bRawStatusData[23])
729         {
730                 *eFormat = format_flashpix;
731         }
732         else
733         {
734                 *eFormat = format_unknown;
735                 ASSERT(false);
736                 return(false);
737         }
738         return(true);
739 }
740
741 //+----------------------------------------------------------------------------
742 //
743 // Function:  GetClock
744 //
745 // Synopsis:
746 //
747 // Arguments: int *piCameraClock
748 //
749 // Returns:   bool
750 //
751 // History:   sgasch Created Header    13 Jan 2000
752 //
753 //+----------------------------------------------------------------------------
754 bool CKodakDC210::GetClock(int *piCameraClock)
755 {
756         if (RefreshProperties())
757         {
758                 *piCameraClock = _bRawStatusData[15] |
759                         (_bRawStatusData[14] << 8) |
760                         (_bRawStatusData[13] << 16) |
761                         (_bRawStatusData[12] << 24);
762                 return(true);
763         }
764         return(false);
765 }
766
767
768 //+----------------------------------------------------------------------------
769 //
770 // Function:  IsUsingJpeg
771 //
772 // Synopsis:
773 //
774 // Arguments: bool *pfJPEG
775 //
776 // Returns:   bool
777 //
778 // History:   sgasch Created Header    13 Jan 2000
779 //
780 //+----------------------------------------------------------------------------
781 bool CKodakDC210::IsUsingJpeg(bool *pfJPEG)
782 {
783         if (3 == _bRawStatusData[23])
784     {
785         *pfJPEG = true;
786     }
787     else if (4 == _bRawStatusData[23])
788     {
789         *pfJPEG = false;
790     }
791     else if (2 == _bRawStatusData[23])
792     {
793         *pfJPEG = false;
794     }
795     else
796     {
797         ASSERT(false);
798         *pfJPEG = false;
799         return(false);
800     }
801     return(true);
802 }
803
804
805 //+----------------------------------------------------------------------------
806 //
807 // Function:  IsUsingFlashPix
808 //
809 // Synopsis:
810 //
811 // Arguments: bool *pfFlashPix
812 //
813 // Returns:   bool
814 //
815 // History:   sgasch Created Header    13 Jan 2000
816 //
817 //+----------------------------------------------------------------------------
818 bool CKodakDC210::IsUsingFlashPix(bool *pfFlashPix)
819 {
820     if (3 == _bRawStatusData[23])
821     {
822         *pfFlashPix = false;
823     }
824     else if (4 == _bRawStatusData[23])
825     {
826         *pfFlashPix = true;
827     }
828     else if (2 == _bRawStatusData[23])
829     {
830         *pfFlashPix = false;
831     }
832     else
833     {
834         ASSERT(false);
835         *pfFlashPix = false;
836         return(false);
837     }
838     return(true);
839 }
840
841
842 //+----------------------------------------------------------------------------
843 //
844 // Function:  GetLifetimePictureCount
845 //
846 // Synopsis:
847 //
848 // Arguments: int *piPictures
849 //
850 // Returns:   bool
851 //
852 // History:   sgasch Created Header    13 Jan 2000
853 //
854 //+----------------------------------------------------------------------------
855 bool CKodakDC210::GetLifetimePictureCount(int *piPictures)
856 {
857     *piPictures = _bRawStatusData[26] | (_bRawStatusData[25] << 8);
858     return(true);
859 }
860
861
862 //+----------------------------------------------------------------------------
863 //
864 // Function:  GetLifetimeFlashCount
865 //
866 // Synopsis:
867 //
868 // Arguments: int *piFlashes
869 //
870 // Returns:   bool
871 //
872 // History:   sgasch Created Header    13 Jan 2000
873 //
874 //+----------------------------------------------------------------------------
875 bool CKodakDC210::GetLifetimeFlashCount(int *piFlashes)
876 {
877     *piFlashes = _bRawStatusData[28] | (_bRawStatusData[27] << 8);
878     return(true);
879 }
880
881
882 //+----------------------------------------------------------------------------
883 //
884 // Function:  IsTimerOn
885 //
886 // Synopsis:
887 //
888 // Arguments: bool *pfTimer
889 //
890 // Returns:   bool
891 //
892 // History:   sgasch Created Header    13 Jan 2000
893 //
894 //+----------------------------------------------------------------------------
895 bool CKodakDC210::IsTimerOn(bool *pfTimer)
896 {
897     if (_bRawStatusData[29])
898     {
899         *pfTimer = true;
900     }
901     else
902     {
903         *pfTimer = false;
904     }
905     return(true);
906 }
907
908
909 //+----------------------------------------------------------------------------
910 //
911 // Function:  IsMemoryCardInserted
912 //
913 // Synopsis:
914 //
915 // Arguments: bool *pfInserted
916 //
917 // Returns:   bool
918 //
919 // History:   sgasch Created Header    13 Jan 2000
920 //
921 //+----------------------------------------------------------------------------
922 bool CKodakDC210::IsMemoryCardInserted(bool *pfInserted)
923 {
924     if (_bRawStatusData[30] & DC210_MEMORY_CARD_INSERTED)
925     {
926         *pfInserted = true;
927     }
928     else
929     {
930         *pfInserted = false;
931     }
932     return(true);
933 }
934
935
936 //+----------------------------------------------------------------------------
937 //
938 // Function:  IsMemoryCardWriteProtected
939 //
940 // Synopsis:
941 //
942 // Arguments: bool *pfWriteProt
943 //
944 // Returns:   bool
945 //
946 // History:   sgasch Created Header    13 Jan 2000
947 //
948 //+----------------------------------------------------------------------------
949 bool CKodakDC210::IsMemoryCardWriteProtected(bool *pfWriteProt)
950 {
951     if (_bRawStatusData[30] & DC210_MEMORY_CARD_WRITE_PROTECTED)
952     {
953         *pfWriteProt = true;
954     }
955     else
956     {
957         *pfWriteProt = false;
958     }
959     return(true);
960 }
961
962
963 //+----------------------------------------------------------------------------
964 //
965 // Function:  IsMemoryCardIllegal
966 //
967 // Synopsis:
968 //
969 // Arguments: bool *pfIllegal
970 //
971 // Returns:   bool
972 //
973 // History:   sgasch Created Header    13 Jan 2000
974 //
975 //+----------------------------------------------------------------------------
976 bool CKodakDC210::IsMemoryCardIllegal(bool *pfIllegal)
977 {
978     if (_bRawStatusData[30] & DC210_MEMORY_CARD_ILLEGAL)
979     {
980         *pfIllegal = true;
981     }
982     else
983     {
984         *pfIllegal = false;
985     }
986     return(true);
987 }
988
989
990 //+----------------------------------------------------------------------------
991 //
992 // Function:  IsMemoryCardFormatted
993 //
994 // Synopsis:
995 //
996 // Arguments: bool *pfFormatted
997 //
998 // Returns:   bool
999 //
1000 // History:   sgasch Created Header    13 Jan 2000
1001 //
1002 //+----------------------------------------------------------------------------
1003 bool CKodakDC210::IsMemoryCardFormatted(bool *pfFormatted)
1004 {
1005     *pfFormatted = (_bRawStatusData[30] & DC210_MEMORY_CARD_FORMATTED);
1006     return(true);
1007 }
1008
1009
1010 //+----------------------------------------------------------------------------
1011 //
1012 // Function:  IsMemoryCardOpened
1013 //
1014 // Synopsis:
1015 //
1016 // Arguments: bool *pfOpened
1017 //
1018 // Returns:   bool
1019 //
1020 // History:   sgasch Created Header    13 Jan 2000
1021 //
1022 //+----------------------------------------------------------------------------
1023 bool CKodakDC210::IsMemoryCardOpened(bool *pfOpened)
1024 {
1025     *pfOpened = (_bRawStatusData[30] & DC210_MEMORY_CARD_OPENED);
1026     return(true);
1027 }
1028
1029
1030 //+----------------------------------------------------------------------------
1031 //
1032 // Function:  GetMemoryCardBitvector
1033 //
1034 // Synopsis:
1035 //
1036 // Arguments: BYTE *pbBitv
1037 //
1038 // Returns:   bool
1039 //
1040 // History:   sgasch Created Header    13 Jan 2000
1041 //
1042 //+----------------------------------------------------------------------------
1043 bool CKodakDC210::GetMemoryCardBitvector(BYTE *pbBitv)
1044 {
1045     *pbBitv = _bRawStatusData[30];
1046     return(true);
1047 }
1048
1049
1050 //+----------------------------------------------------------------------------
1051 //
1052 // Function:  IsUsingNTSC
1053 //
1054 // Synopsis:
1055 //
1056 // Arguments: bool *pfNTSC
1057 //
1058 // Returns:   bool
1059 //
1060 // History:   sgasch Created Header    13 Jan 2000
1061 //
1062 //+----------------------------------------------------------------------------
1063 bool CKodakDC210::IsUsingNTSC(bool *pfNTSC)
1064 {
1065     *pfNTSC = (_bRawStatusData[31]);
1066     return(true);
1067 }
1068
1069
1070 //+----------------------------------------------------------------------------
1071 //
1072 // Function:  IsUsingPAL
1073 //
1074 // Synopsis:
1075 //
1076 // Arguments: bool *pfPAL
1077 //
1078 // Returns:   bool
1079 //
1080 // History:   sgasch Created Header    13 Jan 2000
1081 //
1082 //+----------------------------------------------------------------------------
1083 bool CKodakDC210::IsUsingPAL(bool *pfPAL)
1084 {
1085     *pfPAL = (_bRawStatusData[31]);
1086     return(true);
1087 }
1088
1089
1090 //+----------------------------------------------------------------------------
1091 //
1092 // Function:  GetNumberPictures
1093 //
1094 // Synopsis:
1095 //
1096 // Arguments: int *piNum
1097 //
1098 // Returns:   bool
1099 //
1100 // History:   sgasch Created Header    13 Jan 2000
1101 //
1102 //+----------------------------------------------------------------------------
1103 bool CKodakDC210::GetNumberPictures(int *piNum)
1104 {
1105     *piNum = _bRawStatusData[57] | (_bRawStatusData[56] << 8);
1106     return(true);
1107 }
1108
1109
1110 //+----------------------------------------------------------------------------
1111 //
1112 // Function:  GetRemainingPicturesLowCompression
1113 //
1114 // Synopsis:
1115 //
1116 // Arguments: int *piNum
1117 //
1118 // Returns:   bool
1119 //
1120 // History:   sgasch Created Header    13 Jan 2000
1121 //
1122 //+----------------------------------------------------------------------------
1123 bool CKodakDC210::GetRemainingPicturesLowCompression(int *piNum)
1124 {
1125     *piNum = _bRawStatusData[69] | (_bRawStatusData[68] << 8);
1126     return(true);
1127 }
1128
1129
1130 //+----------------------------------------------------------------------------
1131 //
1132 // Function:  GetRemainingPicturesMedCompression
1133 //
1134 // Synopsis:
1135 //
1136 // Arguments: int *piNum
1137 //
1138 // Returns:   bool
1139 //
1140 // History:   sgasch Created Header    13 Jan 2000
1141 //
1142 //+----------------------------------------------------------------------------
1143 bool CKodakDC210::GetRemainingPicturesMedCompression(int *piNum)
1144 {
1145     *piNum = _bRawStatusData[71] | (_bRawStatusData[70] << 8);
1146     return(true);
1147 }
1148
1149
1150 //+----------------------------------------------------------------------------
1151 //
1152 // Function:  GetRemainingPicturesHighCompression
1153 //
1154 // Synopsis:
1155 //
1156 // Arguments: int *piNum
1157 //
1158 // Returns:   bool
1159 //
1160 // History:   sgasch Created Header    13 Jan 2000
1161 //
1162 //+----------------------------------------------------------------------------
1163 bool CKodakDC210::GetRemainingPicturesHighCompression(int *piNum)
1164 {
1165     *piNum = _bRawStatusData[73] | (_bRawStatusData[72] << 8);
1166     return(true);
1167 }
1168
1169
1170 //+----------------------------------------------------------------------------
1171 //
1172 // Function:  GetMemoryCardVolumeLabel
1173 //
1174 // Synopsis:
1175 //
1176 // Arguments: char *szLabel
1177 //
1178 // Returns:   bool
1179 //
1180 // History:   sgasch Created Header    13 Jan 2000
1181 //
1182 //+----------------------------------------------------------------------------
1183 bool CKodakDC210::GetMemoryCardVolumeLabel(char *szLabel)
1184 {
1185     memcpy(szLabel, &(_bRawStatusData[77]), 11);
1186     szLabel[11] = 0;
1187     return(true);
1188 }
1189
1190
1191 //+----------------------------------------------------------------------------
1192 //
1193 // Function:  GetIdString
1194 //
1195 // Synopsis:
1196 //
1197 // Arguments: char *szId
1198 //
1199 // Returns:   bool
1200 //
1201 // History:   sgasch Created Header    13 Jan 2000
1202 //
1203 //+----------------------------------------------------------------------------
1204 bool CKodakDC210::GetIdString(char *szId)
1205 {
1206     memcpy(szId, &(_bRawStatusData[90]), 32);
1207     szId[32] = 0;
1208     return(true);
1209 }
1210
1211
1212 //+----------------------------------------------------------------------------
1213 //
1214 // Function:  GetTimeValue
1215 //
1216 // Synopsis:
1217 //
1218 // Arguments: int *piClock
1219 //
1220 // Returns:   bool
1221 //
1222 // History:   sgasch Created Header    13 Jan 2000
1223 //
1224 //+----------------------------------------------------------------------------
1225 bool CKodakDC210::GetTimeValue(int *piClock)
1226 {
1227         if (RefreshProperties())
1228         {
1229                 *piClock = _bRawStatusData[15] |
1230                         (_bRawStatusData[14] << 8) |
1231                         (_bRawStatusData[13] << 16) |
1232                         (_bRawStatusData[12] << 24);
1233                 return(true);
1234         }
1235         return(false);
1236 }
1237
1238
1239 //+----------------------------------------------------------------------------
1240 //
1241 // Function:  GetTimeString
1242 //
1243 // Synopsis:
1244 //
1245 // Arguments: char *pszTime
1246 //
1247 // Returns:   bool
1248 //
1249 // History:   sgasch Created Header    13 Jan 2000
1250 //
1251 //+----------------------------------------------------------------------------
1252 bool CKodakDC210::GetTimeString(char *pszTime)
1253 {
1254     static char buf[128];
1255     int iCameraTime;
1256     int iTime;
1257     int iSize;
1258         
1259     memset(buf, 0, 128);
1260     GetTimeValue(&iCameraTime);
1261     iTime = 852094800 + (iCameraTime / 2);
1262     iSize =  strftime(buf, 127, "%v %r", localtime( (time_t *) &iTime));
1263     strcpy(pszTime, buf);
1264
1265     return(true);
1266 }
1267
1268
1269 //+----------------------------------------------------------------------------
1270 //
1271 // Function:  GetTimeMinutes
1272 //
1273 // Synopsis:
1274 //
1275 // Arguments: int *piMin
1276 //
1277 // Returns:   bool
1278 //
1279 // History:   sgasch Created Header    13 Jan 2000
1280 //
1281 //+----------------------------------------------------------------------------
1282 bool CKodakDC210::GetTimeMinutes(int *piMin)
1283 {
1284         int iCameraTime;
1285     int iTime;
1286     struct tm *pTime;
1287
1288     (void) GetTimeValue(&iCameraTime);
1289     iTime = 852094800 + (iCameraTime / 2);
1290     pTime = localtime( (time_t *) &iTime);
1291     *piMin = pTime->tm_min;
1292     return(true);
1293 }
1294
1295
1296 //+----------------------------------------------------------------------------
1297 //
1298 // Function:  GetTimeHours
1299 //
1300 // Synopsis:
1301 //
1302 // Arguments: int *piHrs
1303 //
1304 // Returns:   bool
1305 //
1306 // History:   sgasch Created Header    13 Jan 2000
1307 //
1308 //+----------------------------------------------------------------------------
1309 bool CKodakDC210::GetTimeHours(int *piHrs)
1310 {
1311         int iCameraTime;
1312     int iTime;
1313     struct tm *pTime;
1314
1315     (void) GetTimeValue(&iCameraTime);
1316     iTime = 852094800 + (iCameraTime / 2);
1317     pTime = localtime( (time_t *) &iTime);
1318     *piHrs = pTime->tm_hour;
1319     return(true);
1320 }
1321
1322
1323 //+----------------------------------------------------------------------------
1324 //
1325 // Function:  GetTimeSeconds
1326 //
1327 // Synopsis:
1328 //
1329 // Arguments: int *piSec
1330 //
1331 // Returns:   bool
1332 //
1333 // History:   sgasch Created Header    13 Jan 2000
1334 //
1335 //+----------------------------------------------------------------------------
1336 bool CKodakDC210::GetTimeSeconds(int *piSec)
1337 {
1338     int iCameraTime;
1339     int iTime;
1340     struct tm *pTime;
1341
1342     (void) GetTimeValue(&iCameraTime);
1343     iTime = 852094800 + (iCameraTime / 2);
1344     pTime = localtime( (time_t *) &iTime);
1345     *piSec = pTime->tm_sec;
1346     return(true);
1347 }
1348
1349
1350 //+----------------------------------------------------------------------------
1351 //
1352 // Function:  GetTimeMonth
1353 //
1354 // Synopsis:
1355 //
1356 // Arguments: int *piMon
1357 //
1358 // Returns:   bool
1359 //
1360 // History:   sgasch Created Header    13 Jan 2000
1361 //
1362 //+----------------------------------------------------------------------------
1363 bool CKodakDC210::GetTimeMonth(int *piMon)
1364 {
1365     int iCameraTime;
1366     int iTime;
1367     struct tm *pTime;
1368
1369     (void) GetTimeValue(&iCameraTime);
1370     iTime = 852094800 + (iCameraTime / 2);
1371     pTime = localtime( (time_t *) &iTime);
1372     *piMon = pTime->tm_mon + 1;
1373     return(true);
1374 }
1375
1376
1377 //+----------------------------------------------------------------------------
1378 //
1379 // Function:  GetTimeDay
1380 //
1381 // Synopsis:
1382 //
1383 // Arguments: int *piDay
1384 //
1385 // Returns:   bool
1386 //
1387 // History:   sgasch Created Header    13 Jan 2000
1388 //
1389 //+----------------------------------------------------------------------------
1390 bool CKodakDC210::GetTimeDay(int *piDay)
1391 {
1392     int iCameraTime;
1393     int iTime;
1394     struct tm *pTime;
1395
1396     (void) GetTimeValue(&iCameraTime);
1397     iTime = 852094800 + (iCameraTime / 2);
1398     pTime = localtime( (time_t *) &iTime);
1399     *piDay = pTime->tm_mday;
1400     return(true);
1401 }
1402
1403
1404 //+----------------------------------------------------------------------------
1405 //
1406 // Function:  GetTimeYear
1407 //
1408 // Synopsis:
1409 //
1410 // Arguments: int *piYear
1411 //
1412 // Returns:   bool
1413 //
1414 // History:   sgasch Created Header    13 Jan 2000
1415 //
1416 //+----------------------------------------------------------------------------
1417 bool CKodakDC210::GetTimeYear(int *piYear)
1418 {
1419     int iCameraTime;
1420     int iTime;
1421     struct tm *pTime;
1422
1423     (void) GetTimeValue(&iCameraTime);
1424     iTime = 852094800 + (iCameraTime / 2);
1425     pTime = localtime( (time_t *) &iTime);
1426     *piYear = pTime->tm_year + 1900;
1427     return(true);
1428 }
1429
1430
1431 //+----------------------------------------------------------------------------
1432 //
1433 // Function:  SetFlashState
1434 //
1435 // Synopsis:
1436 //
1437 // Arguments: bool fState
1438 //
1439 // Returns:   bool
1440 //
1441 // History:   sgasch Created Header    15 Jan 2000
1442 //
1443 //+----------------------------------------------------------------------------
1444 bool CKodakDC210::SetFlashState(bool fState)
1445 {
1446         DC210_FLASH_STATE eState;
1447
1448
1449     //
1450     // Precondition: we are initialized.
1451     //
1452     ASSERT(_fInitialized);
1453
1454     //
1455     // Call the other SetFlashState routine.
1456     //
1457         (fState) ? eState = flash_fill : eState = flash_off;
1458         return(SetFlashState(eState));
1459 }
1460
1461
1462 //+----------------------------------------------------------------------------
1463 //
1464 // Function:  SetFlashState
1465 //
1466 // Synopsis:
1467 //
1468 // Arguments: DC210_FLASH_STATE eState
1469 //
1470 // Returns:   bool
1471 //
1472 // History:   sgasch Created Header    15 Jan 2000
1473 //
1474 //+----------------------------------------------------------------------------
1475 bool CKodakDC210::SetFlashState(DC210_FLASH_STATE eState)
1476 {
1477         //
1478         // Pre: we are initialized.
1479         //
1480         ASSERT(_fInitialized);
1481
1482     //
1483     // Send the command
1484     //
1485     if (!SendCommand(DC210_SET_FLASH, (BYTE) eState, 0, 0, 0))
1486     {
1487         Trace("SetFlashState: unable to send command.\n");
1488         ASSERT(false);
1489         return(false);
1490     }
1491
1492     //
1493     // Await reply
1494     //
1495     if (!CommandComplete())
1496     {
1497         Trace("SetFlashState: did not receive command complete "
1498               "signal.\n");
1499         ASSERT(false);
1500         return(false);
1501     }
1502
1503     //
1504     // Refresh status block
1505     //
1506     if (!RefreshProperties())
1507     {
1508         Trace("SetFlashState: Failed to refresh status.\n");
1509         ASSERT(false);
1510         return(false);
1511     }
1512
1513     //
1514     // Success
1515     //
1516     return(true);
1517 }
1518
1519
1520 bool CKodakDC210::EraseAllPictures(void)
1521 {
1522         //
1523         // Precondition: we are initialized
1524         //
1525         ASSERT(_fInitialized);
1526
1527         //
1528         // Send the command
1529         //
1530         if (!SendCommand(DC210_ERASE, 0xFF, 0xFF, 0, 0))
1531         {
1532                 Trace("EraseAllPictures: Failed to send command.\n");
1533                 ASSERT(false);
1534                 return(false);
1535         }
1536
1537         //
1538         // Wait for completion
1539         //
1540         if (!CommandComplete())
1541         {
1542                 Trace("EraseAllPictures: Failed to get command complete signal.\n");
1543                 ASSERT(false);
1544                 return(false);
1545         }
1546
1547         //
1548         // All pictures were supposedly deleted, let's refresh camera status...
1549         //
1550         if (!RefreshProperties())
1551         {
1552                 Trace("EraseAllPictures: Failed to refresh status.\n");
1553                 ASSERT(false);
1554                 return(false);
1555         }
1556
1557         //
1558         // Success
1559         //
1560         return(true);
1561 }
1562
1563 bool CKodakDC210::SetResolution(int iWidth, int iHeight)
1564 {
1565         BYTE bResolutionCode;                // code we need to send to the camera
1566
1567         //
1568         // Preconditions: we are initialized and the resolution is supported
1569         //
1570         ASSERT(_fInitialized);
1571
1572         //
1573         // DC210's support two resolutions, 640x480 and 1152x864.
1574         //
1575         if ((iHeight == 480) && (iWidth == 640))
1576         {
1577                 bResolutionCode = 0;
1578         }
1579         else if ((iHeight == 864) && (iWidth == 1152))
1580         {
1581                 bResolutionCode = 1;
1582         }
1583         else
1584         {
1585                 Trace("SetResolution: Unsupported resolution.  Supported "
1586                           "settings are 640x480 and 1152x864.\n");
1587                 return(false);
1588         }
1589
1590         //
1591         // Send the command
1592         //
1593         if (!SendCommand(DC210_SET_RESOLUTION, bResolutionCode, 0, 0, 0))
1594         {
1595                 Trace("SetResolution: Error sending command, aborting.\n");
1596                 ASSERT(false);
1597                 return(false);
1598         }
1599
1600         //
1601         // Await the command complete signal
1602         //
1603         if (!CommandComplete())
1604         {
1605                 Trace("SetResolution: Did not receive command completion "
1606                           "signal, aborting.\n");
1607                 ASSERT(false);
1608                 return(false);
1609         }
1610
1611         //
1612         // Refresh status block
1613         //
1614         if (!RefreshProperties())
1615         {
1616                 Trace("SetResolution: Failed to refresh status.\n");
1617                 ASSERT(false);
1618                 return(false);
1619         }
1620
1621         //
1622         // Success.
1623         //
1624         return(true);
1625 }
1626
1627
1628 //+----------------------------------------------------------------------------
1629 //
1630 // Function:  Reset
1631 //
1632 // Synopsis:  This command resets the camera to the system default settings:
1633 //
1634 //            (1) Flash mode is auto
1635 //            (2) No red-eye reduction flashes
1636 //            (3) Wide angle zoom position
1637 //            (4) Timer off
1638 //            (5) Exposure compensation zero
1639 //            (6) Compression low (lowest)
1640 //            (7) Resolution high (1152x864)
1641 //            (8) Video out mode NTSC
1642 //            (9) Date/Time reset to 1/1/1997 0:00
1643 //           (10) Quickview on
1644 //           (11) Preview off
1645 //           (12) Baud rate 9600
1646 //
1647 // Arguments: void
1648 //
1649 // Returns:   bool - true if successful
1650 //
1651 // History:   sgasch Created Header    8 Jun 1999
1652 //
1653 //+----------------------------------------------------------------------------
1654 bool CKodakDC210::Reset(void)
1655 {
1656         //
1657         // Precondition: we are initialized
1658         //
1659         ASSERT(_fInitialized);
1660
1661         //
1662         // Send it...
1663         //
1664         if (!SendCommand(DC210_RESET, 0, 0, 0, 0))
1665         {
1666                 Trace("Reset: unable to send command.\n");
1667                 ASSERT(false);
1668                 return(false);
1669         }
1670
1671         //
1672         // Since they will change the serial baud rate to 9600, we will match.
1673         //
1674         if (!_pSerialPort->SetBaudrate(9600))
1675         {
1676                 Trace("Reset: Cannot set serial port baud rate to 9600.\n");
1677                 ASSERT(false);
1678                 return(false);
1679         }
1680
1681         //
1682         // Wait for completion.
1683         //
1684         if (!CommandComplete())
1685         {
1686                 Trace("Reset: command complete signal not received.\n");
1687                 ASSERT(false);
1688                 return(false);
1689         }
1690
1691         //
1692         // Refresh status block
1693         //
1694         if (!RefreshProperties())
1695         {
1696                 Trace("Reset: Failed to refresh status.\n");
1697                 ASSERT(false);
1698                 return(false);
1699         }
1700
1701         //
1702         // Success
1703         //
1704         return(true);
1705 }
1706
1707
1708 //+----------------------------------------------------------------------------
1709 //
1710 // Function:  SetCompressionState
1711 //
1712 // Synopsis:
1713 //
1714 // Arguments: DC210_COMPRESSION_STATE eCompression
1715 //
1716 // Returns:   bool
1717 //
1718 // History:   sgasch Created Header    15 Jan 2000
1719 //
1720 //+----------------------------------------------------------------------------
1721 bool CKodakDC210::SetCompressionState(DC210_COMPRESSION_STATE eCompression)
1722 {
1723         BYTE bCode;
1724
1725         //
1726         // Precondition: we are initialized.
1727         //
1728         ASSERT(_fInitialized);
1729
1730         switch (eCompression)
1731         {
1732                 case compression_low:
1733                         bCode = 1;
1734                         break;
1735                 case compression_medium:
1736                         bCode = 2;
1737                         break;
1738                 case compression_high:
1739                         bCode = 3;
1740                         break;
1741                 default:
1742                         Trace("SetCompressionState: bad parameter.\n");
1743                         return(false);
1744         }
1745         
1746         //
1747         // Send the command to the camera.
1748         //
1749         if (!SendCommand(DC210_SET_COMPRESSION, bCode, 0, 0, 0))
1750         {
1751                 Trace("SetCompressionState: Failed to send command.\n");
1752                 ASSERT(FALSE);
1753                 return(false);
1754         }
1755
1756         //
1757         // Wait for the camera's command complete code.
1758         //
1759         if (!CommandComplete())
1760         {
1761                 Trace("SetCompressionState: Did not receive command completion "
1762                           "signal.\n");
1763                 ASSERT(FALSE);
1764                 return(false);
1765         }
1766
1767         //
1768         // Success
1769         //
1770         return(true);
1771 }
1772
1773
1774 //+----------------------------------------------------------------------------
1775 //
1776 // Function:  SetZoomState
1777 //
1778 // Synopsis:
1779 //
1780 // Arguments: DC210_ZOOM_STATE eZoom
1781 //
1782 // Returns:   bool
1783 //
1784 // History:   sgasch Created Header    15 Jan 2000
1785 //
1786 //+----------------------------------------------------------------------------
1787 bool CKodakDC210::SetZoomState(DC210_ZOOM_STATE eZoom)
1788 {
1789         BYTE bCode;
1790
1791         //
1792         // Pre: we are initialized.
1793         //
1794         ASSERT(_fInitialized);
1795
1796         switch (eZoom)
1797         {
1798                 case zoom_fully_zoomed:
1799                         bCode = 0;
1800                         break;
1801                 case zoom_3:
1802                         bCode = 1;
1803                         break;
1804                 case zoom_2:
1805                         bCode = 2;
1806                         break;
1807                 case zoom_1:
1808                         bCode = 3;
1809                         break;
1810                 case zoom_wideangle:
1811                         bCode = 4;
1812                         break;
1813                 case zoom_closeup:
1814                         bCode = 5;
1815                         break;
1816                 default:
1817                         Trace("SetZoomState: invalid parameter.\n");
1818                         return(false);
1819         }
1820
1821         //
1822         // Send the command to the camera.
1823         //
1824         if (!SendCommand(DC210_SET_ZOOM, bCode, 0, 0, 0))
1825         {
1826                 Trace("SetZoomState: Failed to send command.\n");
1827                 ASSERT(FALSE);
1828                 return(false);
1829         }
1830
1831         //
1832         // Wait for the camera's command complete code.
1833         //
1834         if (!CommandComplete())
1835         {
1836                 Trace("SetZoomState: Did not receive command completion signal.\n");
1837                 ASSERT(FALSE);
1838                 return(false);
1839         }
1840
1841         //
1842         // Success.
1843         //
1844         return(true);
1845 }
1846
1847 //+----------------------------------------------------------------------------
1848 //
1849 // Function:  ToggleShutterDelay
1850 //
1851 // Synopsis:
1852 //
1853 // Arguments: BOOL fEnable
1854 //
1855 // Returns:   bool
1856 //
1857 // History:   sgasch Created Header    15 Jan 2000
1858 //
1859 //+----------------------------------------------------------------------------
1860 bool CKodakDC210::ToggleShutterDelay(BOOL fEnable)
1861 {
1862         BYTE bCode = fEnable;
1863
1864         //
1865         // Pre: we are initialized.
1866         //
1867         ASSERT(_fInitialized);
1868
1869         //
1870         // Send the command to the camera.
1871         //
1872         if (!SendCommand(DC210_SET_SHUTTER_DELAY, bCode, 0, 0, 0))
1873         {
1874                 Trace("ToggleShutterDelay: Failed to send command.\n");
1875                 ASSERT(FALSE);
1876                 return(false);
1877         }
1878
1879         //
1880         // Wait for the camera's command complete code.
1881         //
1882         if (!CommandComplete())
1883         {
1884                 Trace("ToggleShutterDelay: Did not receive command completion "
1885                           "signal.\n");
1886                 ASSERT(FALSE);
1887                 return(false);
1888         }
1889
1890         //
1891         // Success
1892         //
1893         return(true);
1894 }
1895
1896 //+----------------------------------------------------------------------------
1897 //
1898 // Function:  SetPictureFormat
1899 //
1900 // Synopsis:
1901 //
1902 // Arguments: DC210_FILE_FORMAT eFormat
1903 //
1904 // Returns:   bool
1905 //
1906 // History:   sgasch Created Header    15 Jan 2000
1907 //
1908 //+----------------------------------------------------------------------------
1909 bool CKodakDC210::SetPictureFormat(DC210_FILE_FORMAT eFormat)
1910 {
1911         int iParam = eFormat + 2;
1912
1913         //
1914         // Send the command
1915         //
1916         if (!SendCommand(DC210_SET_FORMAT, iParam, 0, 0, 0))
1917         {
1918                 Trace("SetPictureFormat: unable to send command.\n");
1919                 ASSERT(FALSE);
1920                 return(false);
1921         }
1922
1923         //
1924         // Await reply
1925         //
1926         if (!CommandComplete())
1927         {
1928                 Trace("SetPictureFormat: did not receive command complete signal.\n");
1929                 ASSERT(FALSE);
1930                 return(false);
1931         }
1932
1933         //
1934         // Refresh status block
1935         //
1936         if (!RefreshProperties())
1937         {
1938                 Trace("SetPictureFormat: Failed to refresh status.\n");
1939                 ASSERT(FALSE);
1940                 return(false);
1941         }
1942
1943         //
1944         // Success
1945         //
1946         return(true);
1947 }
1948
1949
1950 bool CKodakDC210::SetExposureCompensationValue(float floatValue)
1951 {
1952         return(true);
1953 }
1954
1955 bool CKodakDC210::FormatMemoryCard(void)
1956 {
1957         return(true);
1958 }
1959
1960 bool CKodakDC210::SetIdString(char *szId)
1961 {
1962         return(true);
1963 }
1964
1965
1966
1967
1968
1969
1970
1971 //-----------------------------------------------------------------------------
1972 //-----------------------------------------------------------------------------
1973 //-----------------------------------------------------------------------------
1974 //-----------------------------------------------------------------------------
1975 //-----------------------------------------------------------------------------
1976 //-----------------------------------------------------------------------------
1977 //-----------------------------------------------------------------------------
1978 //-----------------------------------------------------------------------------
1979 //-----------------------------------------------------------------------------
1980
1981
1982
1983
1984
1985 //+----------------------------------------------------------------------------
1986 //
1987 // Function:  SendCommand
1988 //
1989 // Synopsis:  Send a command sequence to the camera.
1990 //
1991 // Arguments: char bCommand
1992 //
1993 // Returns:   bool - true if command sent okay.
1994 //
1995 // History:   sgasch Created Header    4 Jun 1999
1996 //
1997 //+----------------------------------------------------------------------------
1998 bool CKodakDC210::SendCommand(int bCommand, BYTE arg1, BYTE arg2, BYTE arg3,
1999                                                           BYTE arg4)
2000 {
2001         BYTE buf[8];                           // buffer for building cmd to camera
2002
2003         //
2004         // Preconditions: the command is valid, we do _not_ assert that we
2005         // are initialized 'cause this can be called in the constructor before
2006         // we are fully initialized...
2007         //
2008         ASSERT(bCommand <= 0xFF);
2009         ASSERT(bCommand >= 0);
2010
2011         //
2012         // Fill in the buffer with the command to the camera.
2013         //
2014         buf[0] = bCommand;
2015         buf[1] = 0;
2016         buf[2] = arg1;
2017         buf[3] = arg2;
2018         buf[4] = arg3;
2019         buf[5] = arg4;
2020         buf[6] = 0;
2021         buf[7] = 0x1A;
2022
2023         //
2024         // Send the command to the port.
2025         //
2026         if (!_pSerialPort->Write(buf, 8))
2027         {
2028                 Trace("SendCommand: write error?!?\n");
2029                 ASSERT(false);
2030                 return(false);
2031         }
2032         
2033         //
2034         // The camera should acknowledge us, if it got the command...
2035         //
2036         if (!GetAck())
2037         {
2038                 Trace("SendCommand: ACK not received from camera.\n"
2039                           "SendCommand: %x is an illegal command.\n", bCommand);
2040                 return(false);
2041         }
2042
2043         //
2044         // Success
2045         //
2046         return(true);
2047 }
2048
2049
2050 //+----------------------------------------------------------------------------
2051 //
2052 // Function:  GetAck
2053 //
2054 // Synopsis:  Read a command byte from the port and see if it's an ACK.
2055 //
2056 // Arguments: void
2057 //
2058 // Returns:   bool - true if successful ACK received, false otherwise
2059 //
2060 // History:   sgasch Created Header    4 Jun 1999
2061 //
2062 //+----------------------------------------------------------------------------
2063 bool CKodakDC210::GetAck(void)
2064 {
2065         BYTE buf;                              // buffer for byte from camera
2066
2067         //
2068         // The next byte back from the camera is an ACK or a NAK
2069         //
2070         if (!_pSerialPort->Read(&buf, 1))
2071         {
2072                 Trace("GetAck: Read error.\n");
2073                 ASSERT(false);
2074                 return(false);
2075         }
2076
2077         if (DC210_COMMAND_ACK != buf)
2078         {
2079                 printf("GetAck: Received %x, not ACK.\n", buf);
2080                 return(false);
2081         }
2082
2083         //
2084         // Success
2085         //
2086         return(true);
2087 }
2088
2089
2090 //+----------------------------------------------------------------------------
2091 //
2092 // Function:  CommandComplete
2093 //
2094 // Synopsis:  Once we have sent a command string off to the camera and
2095 //            it has replied with an ACK we have to wait until the camera
2096 //            tells us that it's done doing the command.  The host interface
2097 //            spec says that if it is bust for more than two seconds it will
2098 //            send BUSY signals so we know it's still there but working.
2099 //
2100 // Arguments: void
2101 //
2102 // Returns:   bool - true if successful
2103 //
2104 // History:   sgasch Created Header    8 Jun 1999
2105 //
2106 //+----------------------------------------------------------------------------
2107 bool CKodakDC210::CommandComplete(void)
2108 {
2109         BYTE bStatus;                         // a byte from the camera
2110
2111         //
2112         // Get data from the camera and keep doing so while it's "busy"...
2113         //
2114         do
2115         {
2116                 _pSerialPort->Read(&bStatus, 1);
2117         }
2118         while(bStatus == DC210_BUSY);
2119
2120         //
2121         // If it didn't say "complete" then there was an error with the command.
2122         //
2123         if (DC210_COMMAND_COMPLETE != bStatus)
2124         {
2125                 Trace("CommandComplete: Camera reports error code %x.\n", bStatus);
2126                 return(false);
2127         }
2128
2129         //
2130         // Success
2131         //
2132         return(true);
2133 }
2134
2135
2136 //+----------------------------------------------------------------------------
2137 //
2138 // Function:  ReadPacket
2139 //
2140 // Synopsis:
2141 //
2142 // Arguments: BYTE *buf,
2143 //            int iPacketSize
2144 //
2145 // Returns:   bool
2146 //
2147 // History:   sgasch Created Header    13 Jan 2000
2148 //
2149 //+----------------------------------------------------------------------------
2150 bool CKodakDC210::ReadPacket(BYTE *buf, int iPacketSize)
2151 {
2152         BYTE bControl;                         // packet control byte from camera
2153         BYTE bChecksumFromCamera;              // checksum from camera
2154         BYTE bChecksumComputed = 0;            // checksum we compute from data
2155         int iAttempts = 0;                     // loop termination guarantor
2156
2157         //
2158         // Preconditions: we are initialized, the packet size is good, and the
2159         // pointer is good.
2160         //
2161         ASSERT(GOOD_PTR(buf));
2162         if ((iPacketSize != 1024) &&
2163                 (iPacketSize != 512) &&
2164                 (iPacketSize != 256) &&
2165                 (iPacketSize != 16))
2166         {
2167                 Trace("ReadPacket: Invalid packet size.\n");
2168                 return(false);
2169         }
2170         ASSERT(_pSerialPort);
2171
2172         //
2173         // Loop reading packets until we get one with a checksum match.
2174         //
2175         do
2176         {
2177                 //
2178                 // Read the control byte first.
2179                 //
2180                 if (!_pSerialPort->Read(&bControl, 1))
2181                 {
2182                         Trace("ReadPacket: Read error?\n");
2183                         ASSERT(false);
2184                         return(false);
2185                 }
2186                 
2187                 //
2188                 // This byte must always be 0x01, according to the host
2189                 // interface spec.
2190                 //
2191                 if (bControl != DC210_NORMAL_RECEIVE_PACKET)
2192                 {
2193                         Trace("ReadPacket: Illegal packet control byte from "
2194                                   "camera? (%x).\n", bControl);
2195                         return(false);
2196                 }
2197                 
2198                 //
2199                 // Read the packet data itself.
2200                 //
2201                 if (!_pSerialPort->Read(buf, iPacketSize))
2202                 {
2203                         Trace("ReadPacket: Read error?\n");
2204                         ASSERT(false);
2205                         return(false);
2206                 }
2207                 
2208                 //
2209                 // Read the checksum the camera computed.
2210                 //
2211                 if (!_pSerialPort->Read(&bChecksumFromCamera, 1))
2212                 {
2213                         Trace("ReadPacket: Error reading checksum from camera.\n");
2214                         ASSERT(false);
2215                         return(false);
2216                 }
2217                 
2218                 //
2219                 // Compute the checksum based on the data and compare it to the
2220                 // one the camera send... does it match?
2221                 //
2222                 ComputeChecksum(&bChecksumComputed, buf, iPacketSize);
2223                 if (bChecksumComputed == bChecksumFromCamera)
2224                 {
2225                         //
2226                         // Yes, it matched -- send "good packet" to the camera.
2227                         //
2228                         if (!_pSerialPort->WriteByte(DC210_CORRECT_PACKET))
2229                         {
2230                                 Trace("ReadPacket: Could not confirm packet reciept to the "
2231                                           "camera.\n");
2232                                 ASSERT(false);
2233                                 return(false);
2234                         }
2235                 }
2236                 else
2237                 {
2238                         //
2239                         // No match, garbled packet, request a resend.
2240                         //
2241                         if (!_pSerialPort->WriteByte(DC210_ILLEGAL_PACKET))
2242                         {
2243                                 Trace("ReadPacket: Could not ask camera for resend.\n");
2244                                 ASSERT(false);
2245                                 return(false);
2246                         }
2247                 }
2248         }
2249         //
2250         // Continue to loop while the packet is bad and we have not yet
2251         // reached the upper limit to how many attempts to make.
2252         //
2253         while ((bChecksumComputed != bChecksumFromCamera) &&
2254                    (++iAttempts < g_iMaxAttempts));
2255
2256         //
2257         // If we're here because of too many bad packets, tell the camera to
2258         // abort the send.
2259         //
2260         if (iAttempts >= _iMaxAttempts)
2261         {
2262                 Trace("ReadPacket: Too many illegal packets received, giving up.\n");
2263                 if (!_pSerialPort->WriteByte(DC210_ABORT))
2264                 {
2265                         Trace("ReadPacket: Could not abort the communication.\n");
2266                 }
2267                 ASSERT(false);
2268                 return(false);
2269         }
2270
2271         //
2272         // Success
2273         //
2274         return(true);
2275 }
2276
2277
2278 //+----------------------------------------------------------------------------
2279 //
2280 // Function:  SendPacket
2281 //
2282 // Synopsis:  Send a packet of data to the camera given the packet size,
2283 //            a control byte, and the data itself.
2284 //
2285 // Arguments: BYTE bControl - the control byte
2286 //            BYTE *buf - the data
2287 //            int iLength - how large is the packet
2288 //
2289 // Returns:   bool - true on success
2290 //
2291 // History:   sgasch Created Header    8 Jun 1999
2292 //
2293 //+----------------------------------------------------------------------------
2294 bool CKodakDC210::SendPacket(BYTE bControl, BYTE *buf, int iLength)
2295 {
2296         int iAttempts = 0;                     // loop termination guarantor
2297         BYTE bConfirm;                         // confirmation byte from camera
2298         BYTE bChecksum;                        // checksum we compute for packet
2299
2300         //
2301         // Preconditions: we are initialized, the control byte is valid, the
2302         // buf ptr is good, and the length is good.
2303         //
2304         ASSERT(GOOD_PTR(buf));
2305         if ((iLength != 58) && (iLength != 255))
2306         {
2307                 Trace("SendPacket: Invalid packet length, aborting.\n");
2308                 return(false);
2309         }
2310         if ((bControl != DC210_NORMAL_PACKET) &&
2311                 (bControl != DC210_FINAL_PACKET) &&
2312                 (bControl != DC210_ABORT_PACKET))
2313         {
2314                 Trace("SendPacket: Invalid control byte, aborting.\n");
2315                 return(false);
2316         }
2317         ASSERT(_fInitialized);
2318         ASSERT(_pSerialPort);
2319
2320         //
2321         // Loop while the camera didn't get the packet.
2322         //
2323         do
2324         {
2325                 //
2326                 // Write the control byte first... this tells the camera if this
2327                 // is just another packet or the last one.
2328                 //
2329                 if (!_pSerialPort->WriteByte(bControl))
2330                 {
2331                         Trace("SendPacket: Error writing control byte, aborting.\n");
2332                         ASSERT(false);
2333                         return(false);
2334                 }
2335
2336                 //
2337                 // Write the packet data.
2338                 //
2339                 if (!_pSerialPort->Write(buf, iLength))
2340                 {
2341                         Trace("SendPacket: Write error sending packet, aborting.\n");
2342                         ASSERT(false);
2343                         return(false);
2344                 }
2345
2346                 //
2347                 // Compute and send the checksum.
2348                 //
2349                 (void) ComputeChecksum(&bChecksum, buf, iLength);
2350                 if (!_pSerialPort->WriteByte(bChecksum))
2351                 {
2352                         Trace("SendPacket: Error writing checksum byte, aborting.\n");
2353                         ASSERT(false);
2354                         return(false);
2355                 }
2356
2357                 //
2358                 // Receive acknowledgement or error from camera... this tells us
2359                 // whether or not we have to resend the packet.
2360                 //
2361                 if (!_pSerialPort->Read(&bConfirm, 1))
2362                 {
2363                         Trace("SendPacket: Did not receive an ack from camera?!?\n");
2364                         ASSERT(false);
2365                         return(false);
2366                 }
2367         }
2368
2369         //
2370         // Continue to loop while the camera wants a resend (due to garbled data
2371         // causing mismatched checksums) or until we reach the limit of packet
2372         // errors.
2373         //
2374         while ((bConfirm != DC210_CORRECT_PACKET) &&
2375                    (++iAttempts < _iMaxAttempts));
2376
2377         //
2378         // If we're here because of many packet failures, tell the camera we
2379         // are aborting the transfer.
2380         //
2381         if (iAttempts >= g_iMaxAttempts)
2382         {
2383                 Trace("SendPacket: Too many packet errors, aborting "
2384                           "communications.\n");
2385                 if (!(_pSerialPort->WriteByte(DC210_ABORT_PACKET)))
2386                 {
2387                         Trace("WritePacket: Could not abort the communication.\n");
2388                 }
2389                 return(false);
2390         }
2391
2392         //
2393         // Success
2394         //
2395         return(true);
2396 }
2397
2398
2399 //+----------------------------------------------------------------------------
2400 //
2401 // Function:  ComputeChecksum
2402 //
2403 // Synopsis:  Compute and return the checksum byte of a packet.  This method
2404 //            is called by ReadPacket to verify the camera's packet integrity
2405 //            and by SendPacket to send a checksum for the camera to verify.
2406 //
2407 // Arguments: BYTE *pbChecksum - checksum computed
2408 //            BYTE *buf - data ptr
2409 //            int iSize - data length
2410 //
2411 // Returns:   bool - true if successful
2412 //
2413 // History:   sgasch Created Header    8 Jun 1999
2414 //
2415 //+----------------------------------------------------------------------------
2416 bool CKodakDC210::ComputeChecksum(BYTE *pbChecksum, BYTE *buf, int iSize)
2417 {
2418         BYTE bChecksum = *buf;                 // checksum begin as start byte
2419         int iCount = 1;                        // loop control
2420
2421         //
2422         // Preconditions: byte ptr must be good, checksum ptr must be good,
2423         // size must be good.
2424         //
2425         ASSERT(GOOD_PTR(pbChecksum));
2426         ASSERT(GOOD_PTR(buf));
2427         if ((iSize <= 0) || (iSize > 10000))
2428         {
2429                 Trace("ComputeChecksum: illegal packet size.\n");
2430                 ASSERT(false);
2431                 return(false);
2432         }
2433                 
2434         //
2435         // Compute the checksum by serially XORing the data bytes together.
2436         //
2437         for (iCount = 1; iCount < iSize; iCount++)
2438         {
2439                 bChecksum ^= *(buf + iCount);
2440         }
2441         *pbChecksum = bChecksum;
2442
2443         //
2444         // Success
2445         //
2446         return(true);
2447 }