moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kstars / kstars / indi / lx200driver.c
blob9c108eb70d94617a503ddc68ca778cfb1e28cd04
1 #if 0
2 LX200 Driver
3 Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com)
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #endif
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include <math.h>
26 #include <sys/time.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <termios.h>
30 #include <time.h>
32 #include "indicom.h"
33 #include "indidevapi.h"
34 #include "lx200driver.h"
36 #define LX200_TIMEOUT 5 /* FD timeout in seconds */
38 int fd;
39 int read_ret, write_ret;
41 /**************************************************************************
42 Basic I/O
43 **************************************************************************/
44 int openPort(const char *portID);
45 int portRead(char *buf, int nbytes, int timeout);
46 int portWrite(const char * buf);
47 int LX200readOut(int timeout);
49 int Connect(const char* device);
50 void Disconnect(void);
52 /**************************************************************************
53 Diagnostics
54 **************************************************************************/
55 char ACK(void);
56 int testTelescope(void);
57 int testAP(void);
59 /**************************************************************************
60 Get Commands: store data in the supplied buffer. Return 0 on success or -1 on failure
61 **************************************************************************/
63 /* Get Double from Sexagisemal */
64 int getCommandSexa(double *value, const char *cmd);
65 /* Get String */
66 int getCommandString(char *data, const char* cmd);
67 /* Get Int */
68 int getCommandInt(int *value, const char* cmd);
69 /* Get tracking frequency */
70 int getTrackFreq(double * value);
71 /* Get site Latitude */
72 int getSiteLatitude(int *dd, int *mm);
73 /* Get site Longitude */
74 int getSiteLongitude(int *ddd, int *mm);
75 /* Get Calender data */
76 int getCalenderDate(char *date);
77 /* Get site Name */
78 int getSiteName(char *siteName, int siteNum);
79 /* Get Number of Bars */
80 int getNumberOfBars(int *value);
81 /* Get Home Search Status */
82 int getHomeSearchStatus(int *status);
83 /* Get OTA Temperature */
84 int getOTATemp(double * value);
85 /* Get time format: 12 or 24 */
86 int getTimeFormat(int *format);
89 /**************************************************************************
90 Set Commands
91 **************************************************************************/
93 /* Set Int */
94 int setCommandInt(int data, const char *cmd);
95 /* Set Sexigesimal */
96 int setCommandXYZ( int x, int y, int z, const char *cmd);
97 /* Common routine for Set commands */
98 int setStandardProcedure(char * writeData);
99 /* Set Slew Mode */
100 int setSlewMode(int slewMode);
101 /* Set Alignment mode */
102 int setAlignmentMode(unsigned int alignMode);
103 /* Set Object RA */
104 int setObjectRA(double ra);
105 /* set Object DEC */
106 int setObjectDEC(double dec);
107 /* Set Calender date */
108 int setCalenderDate(int dd, int mm, int yy);
109 /* Set UTC offset */
110 int setUTCOffset(double hours);
111 /* Set Track Freq */
112 int setTrackFreq(double trackF);
113 /* Set current site longitude */
114 int setSiteLongitude(double Long);
115 /* Set current site latitude */
116 int setSiteLatitude(double Lat);
117 /* Set Object Azimuth */
118 int setObjAz(double az);
119 /* Set Object Altitude */
120 int setObjAlt(double alt);
121 /* Set site name */
122 int setSiteName(char * siteName, int siteNum);
123 /* Set maximum slew rate */
124 int setMaxSlewRate(int slewRate);
125 /* Set focuser motion */
126 int setFocuserMotion(int motionType);
127 /* Set focuser speed mode */
128 int setFocuserSpeedMode (int speedMode);
129 /* Set minimum elevation limit */
130 int setMinElevationLimit(int min);
131 /* Set maximum elevation limit */
132 int setMaxElevationLimit(int max);
134 /**************************************************************************
135 Motion Commands
136 **************************************************************************/
137 /* Slew to the selected coordinates */
138 int Slew(void);
139 /* Synchronize to the selected coordinates and return the matching object if any */
140 int Sync(char *matchedObject);
141 /* Abort slew in all axes */
142 int abortSlew(void);
143 /* Move into one direction, two valid directions can be stacked */
144 int MoveTo(int direction);
145 /* Half movement in a particular direction */
146 int HaltMovement(int direction);
147 /* Select the tracking mode */
148 int selectTrackingMode(int trackMode);
149 /* Select Astro-Physics tracking mode */
150 int selectAPTrackingMode(int trackMode);
152 /**************************************************************************
153 Other Commands
154 **************************************************************************/
155 /* Ensures LX200 RA/DEC format is long */
156 int checkLX200Format(void);
157 /* Select a site from the LX200 controller */
158 int selectSite(int siteNum);
159 /* Select a catalog object */
160 int selectCatalogObject(int catalog, int NNNN);
161 /* Select a sub catalog */
162 int selectSubCatalog(int catalog, int subCatalog);
164 /**********************************************************************
165 * BASIC
166 **********************************************************************/
168 int Connect(const char *device)
170 fprintf(stderr, "Connecting to device %s\n", device);
172 if (openPort(device) < 0)
173 return -1;
174 else
175 return 0;
178 void Disconnect()
180 fprintf(stderr, "Disconnected.\n");
181 close(fd);
184 int testTelescope()
186 int i=0;
187 char ack[1] = { (char) 0x06 };
188 char MountAlign[64];
189 fprintf(stderr, "Testing telescope's connection...\n");
191 for (i=0; i < 2; i++)
193 write(fd, ack, 1);
194 read_ret = portRead(MountAlign, 1, LX200_TIMEOUT);
195 if (read_ret == 1)
196 return 0;
197 usleep(50000);
200 return -1;
203 int testAP()
205 int i=0;
206 char currentDate[64];
208 fprintf(stderr, "Testing telescope's connection...\n");
210 /* We need to test if the telescope is responding
211 / We're going to request the calander date */
212 for (i=0; i < 2; i++)
214 if (!getCalenderDate(currentDate))
215 return 0;
217 usleep(50000);
220 return -1;
225 /**********************************************************************
226 * GET
227 **********************************************************************/
229 char ACK()
231 char ack[1] = { (char) 0x06 };
232 char MountAlign[2];
234 write_ret = write(fd, ack, 1);
236 if (write_ret < 0)
237 return -1;
239 read_ret = portRead(MountAlign, 1, LX200_TIMEOUT);
241 if (read_ret == 1)
242 return MountAlign[0];
243 else
244 return read_ret;
248 int getCommandSexa(double *value, const char * cmd)
250 char tempString[16];
252 tcflush(fd, TCIFLUSH);
254 if (portWrite(cmd) < 0)
255 return -1;
257 if ( (read_ret = portRead(tempString, -1, LX200_TIMEOUT)) < 1)
258 return read_ret;
260 tempString[read_ret - 1] = '\0';
262 if (f_scansexa(tempString, value))
264 fprintf(stderr, "unable to process [%s]\n", tempString);
265 return -1;
268 return 0;
271 int getCommandString(char *data, const char* cmd)
273 char * term;
275 if (portWrite(cmd) < 0)
276 return -1;
278 read_ret = portRead(data, -1, LX200_TIMEOUT);
280 if (read_ret < 1)
281 return read_ret;
283 term = strchr (data, '#');
284 if (term)
285 *term = '\0';
287 fprintf(stderr, "Requested data: %s\n", data);
289 return 0;
292 int getCalenderDate(char *date)
295 int dd, mm, yy;
296 int err;
298 if ( (err = getCommandString(date, "#:GC#")) )
299 return err;
301 /* Meade format is MM/DD/YY */
303 read_ret = sscanf(date, "%d%*c%d%*c%d", &mm, &dd, &yy);
304 if (read_ret < 3)
305 return -1;
307 /* We need to have in in YYYY/MM/DD format */
308 sprintf(date, "20%02d/%02d/%02d", yy, mm, dd);
310 return (0);
314 int getTimeFormat(int *format)
316 char tempString[16];
317 int tMode;
319 if (portWrite("#:Gc#") < 0)
320 return -1;
322 read_ret = portRead(tempString, -1, LX200_TIMEOUT);
324 if (read_ret < 1)
325 return read_ret;
327 tempString[read_ret-1] = '\0';
329 read_ret = sscanf(tempString, "(%d)", &tMode);
331 if (read_ret < 1)
332 return -1;
333 else
334 *format = tMode;
336 return 0;
340 /*int getUTCOffset()
342 char tempString[4];
343 int offSet;
345 portWrite("#:GG#");
347 read_ret = portRead(tempString, 4);
348 if (read_ret)
349 return -1;
351 tempString[3] = '\0';
353 sscanf(tempString, "%d", &offSet);
355 fprintf(stderr, "UTC Offset: %d\n", offSet);
357 return offSet;
360 int getMaxElevationLimit()
362 char tempString[16];
363 int limit;
365 portWrite("#:Go#");
367 read_ret = portRead(tempString, -1, LX200_TIMEOUT);
368 if (read_ret < 1)
369 return -1;
371 tempString[read_ret-1] = '\0';
373 sscanf(tempString, "%d", &limit);
375 fprintf(stderr, "Max elevation limit string is %s\n", tempString);
377 return limit;
380 int getMinElevationLimit()
382 char tempString[16];
383 int limit;
385 portWrite("#:Gh#");
387 read_ret = portRead(tempString, -1, LX200_TIMEOUT);
388 if (read_ret < 1)
389 return -1;
391 tempString[read_ret-1] = '\0';
393 sscanf(tempString, "%d", &limit);
395 fprintf(stderr, "Min elevation limit string is %s\n", tempString);
397 return limit;
402 int getSiteName(char *siteName, int siteNum)
404 char * term;
406 switch (siteNum)
408 case 1:
409 if (portWrite("#:GM#") < 0)
410 return -1;
411 break;
412 case 2:
413 if (portWrite("#:GN#") < 0)
414 return -1;
415 break;
416 case 3:
417 if (portWrite("#:GO#") < 0)
418 return -1;
419 break;
420 case 4:
421 if (portWrite("#:GP#") < 0)
422 return -1;
423 break;
424 default:
425 return -1;
428 read_ret = portRead(siteName, -1, LX200_TIMEOUT);
429 if (read_ret < 1)
430 return read_ret;
432 siteName[read_ret - 1] = '\0';
434 term = strchr (siteName, ' ');
435 if (term)
436 *term = '\0';
438 term = strchr (siteName, '<');
439 if (term)
440 strcpy(siteName, "unused site");
442 fprintf(stderr, "Requested site name: %s\n", siteName);
444 return 0;
447 int getSiteLatitude(int *dd, int *mm)
449 char tempString[16];
451 if (portWrite("#:Gt#") < 0)
452 return -1;
454 read_ret = portRead(tempString, -1, LX200_TIMEOUT);
456 if (read_ret < 1)
457 return read_ret;
459 tempString[read_ret -1] = '\0';
461 if (sscanf (tempString, "%d%*c%d", dd, mm) < 2)
462 return -1;
464 fprintf(stderr, "Requested site latitude in String %s\n", tempString);
465 fprintf(stderr, "Requested site latitude %d:%d\n", *dd, *mm);
467 return 0;
470 int getSiteLongitude(int *ddd, int *mm)
472 char tempString[16];
474 if (portWrite("#:Gg#") < 0)
475 return -1;
477 read_ret = portRead(tempString, -1, LX200_TIMEOUT);
479 if (read_ret < 1)
480 return read_ret;
482 tempString[read_ret -1] = '\0';
484 if (sscanf (tempString, "%d%*c%d", ddd, mm) < 2)
485 return -1;
487 fprintf(stderr, "Requested site longitude in String %s\n", tempString);
488 fprintf(stderr, "Requested site longitude %d:%d\n", *ddd, *mm);
490 return 0;
493 int getTrackFreq(double *value)
495 float Freq;
496 char tempString[16];
498 if (portWrite("#:GT#") < 0)
499 return -1;
501 read_ret = portRead(tempString, -1, LX200_TIMEOUT);
503 if (read_ret < 1)
504 return read_ret;
506 tempString[read_ret] = '\0';
508 /*fprintf(stderr, "Telescope tracking freq str: %s\n", tempString);*/
510 if (sscanf(tempString, "%f#", &Freq) < 1)
511 return -1;
513 *value = (double) Freq;
515 /*fprintf(stderr, "Tracking frequency value is %f\n", Freq);*/
517 return 0;
520 int getNumberOfBars(int *value)
522 char tempString[128];
524 if (portWrite("#:D#") < 0)
525 return -1;
527 read_ret = portRead(tempString, -1, LX200_TIMEOUT);
529 if (read_ret < 0)
530 return read_ret;
532 *value = read_ret -1;
534 return 0;
537 int getHomeSearchStatus(int *status)
539 char tempString[16];
541 if (portWrite("#:h?#") < 0)
542 return -1;
544 read_ret = portRead(tempString, 1, LX200_TIMEOUT);
546 if (read_ret < 1)
547 return read_ret;
549 tempString[1] = '\0';
551 if (tempString[0] == '0')
552 *status = 0;
553 else if (tempString[0] == '1')
554 *status = 1;
555 else if (tempString[0] == '2')
556 *status = 1;
558 return 0;
561 int getOTATemp(double *value)
564 char tempString[16];
565 float temp;
567 if (portWrite("#:fT#") < 0)
568 return -1;
570 read_ret = portRead(tempString, -1, LX200_TIMEOUT);
572 if (read_ret < 1)
573 return read_ret;
575 tempString[read_ret - 1] = '\0';
577 if (sscanf(tempString, "%f", &temp) < 1)
578 return -1;
580 *value = (double) temp;
582 return 0;
586 /**********************************************************************
587 * SET
588 **********************************************************************/
590 int setStandardProcedure(char * data)
592 char boolRet[2];
594 if (portWrite(data) < 0)
595 return -1;
597 read_ret = portRead(boolRet, 1, LX200_TIMEOUT);
599 if (read_ret < 1)
600 return read_ret;
602 if (boolRet[0] == '0')
604 fprintf(stderr, "%s Failed.\n", data);
605 return -1;
608 fprintf(stderr, "%s Successful\n", data);
609 return 0;
614 int setCommandInt(int data, const char *cmd)
617 char tempString[16];
619 snprintf(tempString, sizeof( tempString ), "%s%d#", cmd, data);
621 if (portWrite(tempString) < 0)
622 return -1;
624 return 0;
627 int setMinElevationLimit(int min)
629 char tempString[16];
631 snprintf(tempString, sizeof( tempString ), "#:Sh%02d#", min);
633 return (setStandardProcedure(tempString));
636 int setMaxElevationLimit(int max)
638 char tempString[16];
640 snprintf(tempString, sizeof( tempString ), "#:So%02d*#", max);
642 return (setStandardProcedure(tempString));
646 int setMaxSlewRate(int slewRate)
649 char tempString[16];
651 if (slewRate < 2 || slewRate > 8)
652 return -1;
654 snprintf(tempString, sizeof( tempString ), "#:Sw%d#", slewRate);
656 return (setStandardProcedure(tempString));
661 int setObjectRA(double ra)
664 int h, m, s;
665 char tempString[16];
667 getSexComponents(ra, &h, &m, &s);
669 snprintf(tempString, sizeof( tempString ), "#:Sr %02d:%02d:%02d#", h, m, s);
670 IDLog("Set Object RA String %s\n", tempString);
671 return (setStandardProcedure(tempString));
675 int setObjectDEC(double dec)
677 int d, m, s;
678 char tempString[16];
680 getSexComponents(dec, &d, &m, &s);
682 /* case with negative zero */
683 if (!d && dec < 0)
684 snprintf(tempString, sizeof( tempString ), "#:Sd -%02d:%02d:%02d#", d, m, s);
685 else
686 snprintf(tempString, sizeof( tempString ), "#:Sd %+03d:%02d:%02d#", d, m, s);
688 IDLog("Set Object DEC String %s\n", tempString);
690 return (setStandardProcedure(tempString));
694 int setCommandXYZ(int x, int y, int z, const char *cmd)
696 char tempString[16];
698 snprintf(tempString, sizeof( tempString ), "%s %02d:%02d:%02d#", cmd, x, y, z);
700 return (setStandardProcedure(tempString));
703 int setAlignmentMode(unsigned int alignMode)
705 fprintf(stderr , "Set alignment mode %d\n", alignMode);
707 switch (alignMode)
709 case LX200_ALIGN_POLAR:
710 if (portWrite("#:AP#") < 0)
711 return -1;
712 break;
713 case LX200_ALIGN_ALTAZ:
714 if (portWrite("#:AA#") < 0)
715 return -1;
716 break;
717 case LX200_ALIGN_LAND:
718 if (portWrite("#:AL#") < 0)
719 return -1;
720 break;
723 return 0;
726 int setCalenderDate(int dd, int mm, int yy)
728 char tempString[32];
729 char dumpPlanetaryUpdateString[64];
730 char boolRet[2];
731 yy = yy % 100;
733 snprintf(tempString, sizeof( tempString ), "#:SC %02d/%02d/%02d#", mm, dd, yy);
735 if (portWrite(tempString) < 0)
736 return -1;
738 read_ret = portRead(boolRet, 1, LX200_TIMEOUT);
740 if (read_ret < 1)
741 return read_ret;
743 boolRet[1] = '\0';
745 if (boolRet[0] == '0')
746 return -1;
748 /* Read dumped data */
749 portRead(dumpPlanetaryUpdateString, -1, LX200_TIMEOUT);
750 portRead(dumpPlanetaryUpdateString, -1, 5);
752 return 0;
755 int setUTCOffset(double hours)
757 char tempString[16];
759 /*TODO add fractions*/
760 snprintf(tempString, sizeof( tempString ), "#:SG %+03d#", (int) hours);
762 fprintf(stderr, "UTC string is %s\n", tempString);
764 return (setStandardProcedure(tempString));
768 int setSiteLongitude(double Long)
770 int d, m, s;
771 char tempString[32];
773 getSexComponents(Long, &d, &m, &s);
775 snprintf(tempString, sizeof( tempString ), "#:Sg%03d:%02d#", d, m);
777 return (setStandardProcedure(tempString));
780 int setSiteLatitude(double Lat)
782 int d, m, s;
783 char tempString[32];
785 getSexComponents(Lat, &d, &m, &s);
787 snprintf(tempString, sizeof( tempString ), "#:St%+03d:%02d:%02d#", d, m, s);
789 return (setStandardProcedure(tempString));
792 int setObjAz(double az)
794 int d,m,s;
795 char tempString[16];
797 getSexComponents(az, &d, &m, &s);
799 snprintf(tempString, sizeof( tempString ), "#:Sz%03d:%02d#", d, m);
801 return (setStandardProcedure(tempString));
805 int setObjAlt(double alt)
807 int d, m, s;
808 char tempString[16];
810 getSexComponents(alt, &d, &m, &s);
812 snprintf(tempString, sizeof( tempString ), "#:Sa%+02d*%02d#", d, m);
814 return (setStandardProcedure(tempString));
818 int setSiteName(char * siteName, int siteNum)
821 char tempString[16];
823 switch (siteNum)
825 case 1:
826 snprintf(tempString, sizeof( tempString ), "#:SM %s#", siteName);
827 break;
828 case 2:
829 snprintf(tempString, sizeof( tempString ), "#:SN %s#", siteName);
830 break;
831 case 3:
832 snprintf(tempString, sizeof( tempString ), "#:SO %s#", siteName);
833 break;
834 case 4:
835 snprintf(tempString, sizeof( tempString ), "#:SP %s#", siteName);
836 break;
837 default:
838 return -1;
841 return (setStandardProcedure(tempString));
844 int setSlewMode(int slewMode)
847 switch (slewMode)
849 case LX200_SLEW_MAX:
850 if (portWrite("#:RS#") < 0)
851 return -1;
852 break;
853 case LX200_SLEW_FIND:
854 if (portWrite("#:RM#") < 0)
855 return -1;
856 break;
857 case LX200_SLEW_CENTER:
858 if (portWrite("#:RC#") < 0)
859 return -1;
860 break;
861 case LX200_SLEW_GUIDE:
862 if (portWrite("#:RG#") < 0)
863 return -1;
864 break;
865 default:
866 break;
869 return 0;
873 int setFocuserMotion(int motionType)
876 switch (motionType)
878 case LX200_FOCUSIN:
879 if (portWrite("#:F+#") < 0)
880 return -1;
881 break;
882 case LX200_FOCUSOUT:
883 if (portWrite("#:F-#") < 0)
884 return -1;
885 break;
888 return 0;
891 int setFocuserSpeedMode (int speedMode)
894 switch (speedMode)
896 case LX200_HALTFOCUS:
897 if (portWrite("#:FQ#") < 0)
898 return -1;
899 break;
900 case LX200_FOCUSFAST:
901 if (portWrite("#:FF#") < 0)
902 return -1;
903 break;
904 case LX200_FOCUSMEDIUM:
905 if (portWrite("#:F3#") < 0)
906 return -1;
907 break;
908 case LX200_FOCUSSLOW:
909 if (portWrite("#:FS#") < 0)
910 return -1;
911 break;
914 return 0;
918 int setTrackFreq(double trackF)
920 char tempString[16];
922 snprintf(tempString, sizeof( tempString ), "#:ST %04.1f#", trackF);
924 return (setStandardProcedure(tempString));
928 /**********************************************************************
929 * Misc
930 *********************************************************************/
932 int Slew()
934 char slewNum[2];
935 char errorMsg[128];
937 if (portWrite("#:MS#") < 0)
938 return -1;
940 read_ret = portRead(slewNum, 1, LX200_TIMEOUT);
942 if (read_ret < 1)
943 return read_ret;
945 slewNum[1] = '\0';
947 if (slewNum[0] == '0')
948 return 0;
950 read_ret = portRead(errorMsg, -1, LX200_TIMEOUT);
952 if (read_ret < 1)
953 return read_ret;
955 if (slewNum[0] == '1')
956 return 1;
957 else return 2;
961 int MoveTo(int direction)
964 switch (direction)
966 case LX200_NORTH:
967 portWrite("#:Mn#");
968 break;
969 case LX200_WEST:
970 portWrite("#:Mw#");
971 break;
972 case LX200_EAST:
973 portWrite("#:Me#");
974 break;
975 case LX200_SOUTH:
976 portWrite("#:Ms#");
977 break;
978 default:
979 break;
982 return 0;
985 int HaltMovement(int direction)
988 switch (direction)
990 case LX200_NORTH:
991 if (portWrite("#:Qn#") < 0)
992 return -1;
993 break;
994 case LX200_WEST:
995 if (portWrite("#:Qw#") < 0)
996 return -1;
997 break;
998 case LX200_EAST:
999 if (portWrite("#:Qe#") < 0)
1000 return -1;
1001 break;
1002 case LX200_SOUTH:
1003 if (portWrite("#:Qs#") < 0)
1004 return -1;
1005 break;
1006 case LX200_ALL:
1007 if (portWrite("#:Q#") < 0)
1008 return -1;
1009 break;
1010 default:
1011 return -1;
1012 break;
1015 return 0;
1019 int abortSlew()
1021 if (portWrite("#:Q#") < 0)
1022 return -1;
1024 return 0;
1027 int Sync(char *matchedObject)
1029 portWrite("#:CM#");
1031 read_ret = portRead(matchedObject, -1, LX200_TIMEOUT);
1033 if (read_ret < 1)
1034 return read_ret;
1036 matchedObject[read_ret-1] = '\0';
1038 /* Sleep 10ms before flushing. This solves some issues with LX200 compatible devices. */
1039 usleep(10000);
1041 tcflush(fd, TCIFLUSH);
1043 return 0;
1046 int selectSite(int siteNum)
1049 switch (siteNum)
1051 case 1:
1052 if (portWrite("#:W1#") < 0)
1053 return -1;
1054 break;
1055 case 2:
1056 if (portWrite("#:W2#") < 0)
1057 return -1;
1058 break;
1059 case 3:
1060 if (portWrite("#:W3#") < 0)
1061 return -1;
1062 break;
1063 case 4:
1064 if (portWrite("#:W4#") < 0)
1065 return -1;
1066 break;
1067 default:
1068 return -1;
1069 break;
1072 return 0;
1076 int selectCatalogObject(int catalog, int NNNN)
1078 char tempString[16];
1080 switch (catalog)
1082 case LX200_STAR_C:
1083 snprintf(tempString, sizeof( tempString ), "#:LS%d#", NNNN);
1084 break;
1085 case LX200_DEEPSKY_C:
1086 snprintf(tempString, sizeof( tempString ), "#:LC%d#", NNNN);
1087 break;
1088 case LX200_MESSIER_C:
1089 snprintf(tempString, sizeof( tempString ), "#:LM%d#", NNNN);
1090 break;
1091 default:
1092 return -1;
1095 if (portWrite(tempString) < 0)
1096 return -1;
1098 return 0;
1101 int selectSubCatalog(int catalog, int subCatalog)
1103 char tempString[16];
1104 switch (catalog)
1106 case LX200_STAR_C:
1107 snprintf(tempString, sizeof( tempString ), "#:LsD%d#", subCatalog);
1108 break;
1109 case LX200_DEEPSKY_C:
1110 snprintf(tempString, sizeof( tempString ), "#:LoD%d#", subCatalog);
1111 break;
1112 case LX200_MESSIER_C:
1113 return 1;
1114 default:
1115 return 0;
1118 return (setStandardProcedure(tempString));
1121 int checkLX200Format()
1124 char tempString[16];
1126 if (portWrite("#:GR#") < 0)
1127 return -1;
1129 read_ret = portRead(tempString, -1, LX200_TIMEOUT);
1131 if (read_ret < 1)
1132 return read_ret;
1134 tempString[read_ret - 1] = '\0';
1136 /* Short */
1137 if (tempString[5] == '.')
1138 if (portWrite("#:U#") < 0)
1139 return -1;
1141 return 0;
1144 int selectTrackingMode(int trackMode)
1147 switch (trackMode)
1149 case LX200_TRACK_DEFAULT:
1150 fprintf(stderr, "Setting tracking mode to sidereal.\n");
1151 if (portWrite("#:TQ#") < 0)
1152 return -1;
1153 break;
1154 case LX200_TRACK_LUNAR:
1155 fprintf(stderr, "Setting tracking mode to LUNAR.\n");
1156 if (portWrite("#:TL#") < 0)
1157 return -1;
1158 break;
1159 case LX200_TRACK_MANUAL:
1160 fprintf(stderr, "Setting tracking mode to CUSTOM.\n");
1161 if (portWrite("#:TM#") < 0)
1162 return -1;
1163 break;
1164 default:
1165 return -1;
1166 break;
1169 return 0;
1173 int selectAPTrackingMode(int trackMode)
1175 switch (trackMode)
1177 /* Lunar */
1178 case 0:
1179 fprintf(stderr, "Setting tracking mode to lunar.\n");
1180 if (portWrite("#:RT0#") < 0)
1181 return -1;
1182 break;
1184 /* Solar */
1185 case 1:
1186 fprintf(stderr, "Setting tracking mode to solar.\n");
1187 if (portWrite("#:RT1#") < 0)
1188 return -1;
1189 break;
1191 /* Sidereal */
1192 case 2:
1193 fprintf(stderr, "Setting tracking mode to sidereal.\n");
1194 if (portWrite("#:RT2#") < 0)
1195 return -1;
1196 break;
1198 /* Zero */
1199 case 3:
1200 fprintf(stderr, "Setting tracking mode to zero.\n");
1201 if (portWrite("#:RT9#") < 0)
1202 return -1;
1203 break;
1205 default:
1206 return -1;
1207 break;
1210 return 0;
1215 /**********************************************************************
1216 * Comm
1217 **********************************************************************/
1219 int openPort(const char *portID)
1221 struct termios ttyOptions;
1223 if ( (fd = open(portID, O_RDWR)) == -1)
1224 return -1;
1226 memset(&ttyOptions, 0, sizeof(ttyOptions));
1227 tcgetattr(fd, &ttyOptions);
1229 /* Control options
1230 charecter size */
1231 ttyOptions.c_cflag &= ~CSIZE;
1232 /* 8 bit, enable read */
1233 ttyOptions.c_cflag |= CREAD | CLOCAL | CS8;
1234 /* no parity */
1235 ttyOptions.c_cflag &= ~PARENB;
1237 /* set baud rate */
1238 cfsetispeed(&ttyOptions, B9600);
1239 cfsetospeed(&ttyOptions, B9600);
1241 /* set input/output flags */
1242 ttyOptions.c_iflag = IGNBRK;
1243 /* no software flow control */
1244 ttyOptions.c_iflag &= ~(IXON|IXOFF|IXANY);
1246 /* Read at least one byte */
1247 ttyOptions.c_cc[VMIN] = 1;
1248 ttyOptions.c_cc[VTIME] = 5;
1250 /* Misc. */
1251 ttyOptions.c_lflag = 0;
1252 ttyOptions.c_oflag = 0;
1254 /* set attributes */
1255 tcsetattr(fd, TCSANOW, &ttyOptions);
1257 /* flush the channel */
1258 tcflush(fd, TCIOFLUSH);
1259 return (fd);
1262 int portWrite(const char * buf)
1264 int nbytes, totalBytesWritten;
1265 int bytesWritten = 0;
1267 nbytes = totalBytesWritten = strlen(buf);
1269 while (nbytes > 0)
1272 bytesWritten = write(fd, buf, nbytes);
1274 if (bytesWritten < 0)
1275 return -1;
1277 buf += bytesWritten;
1278 nbytes -= bytesWritten;
1281 /* Returns the # of bytes written */
1282 return (totalBytesWritten);
1285 int portRead(char *buf, int nbytes, int timeout)
1288 int bytesRead = 0;
1289 int totalBytesRead = 0;
1290 int err;
1292 /* Loop until encountring the '#' char */
1293 if (nbytes == -1)
1295 for (;;)
1297 if ( (err = LX200readOut(timeout)) )
1298 return err;
1300 bytesRead = read(fd, buf, 1);
1302 if (bytesRead < 0 )
1303 return -1;
1305 if (bytesRead)
1306 totalBytesRead++;
1308 if (*buf == '#')
1309 return totalBytesRead;
1311 buf += bytesRead;
1315 while (nbytes > 0)
1317 if ( (err = LX200readOut(timeout)) )
1318 return err;
1320 bytesRead = read(fd, buf, nbytes);
1322 if (bytesRead < 0 )
1323 return -1;
1325 buf += bytesRead;
1326 totalBytesRead++;
1327 nbytes -= bytesRead;
1330 return totalBytesRead;
1333 int LX200readOut(int timeout)
1335 struct timeval tv;
1336 fd_set readout;
1337 int retval;
1339 FD_ZERO(&readout);
1340 FD_SET(fd, &readout);
1342 /* wait for 'timeout' seconds */
1343 tv.tv_sec = timeout;
1344 tv.tv_usec = 0;
1346 /* Wait till we have a change in the fd status */
1347 retval = select (fd+1, &readout, NULL, NULL, &tv);
1349 /* Return 0 on successful fd change */
1350 if (retval > 0)
1351 return 0;
1352 /* Return -1 due to an error */
1353 else if (retval == -1)
1354 return retval;
1355 /* Return -2 if time expires before anything interesting happens */
1356 else
1357 return -2;