You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeedu/kstars/kstars/indi/lx200driver.c

1387 lines
27 KiB

#if 0
LX200 Driver
Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <time.h>
#include "indicom.h"
#include "indidevapi.h"
#include "lx200driver.h"
#define LX200_TIMEOUT 5 /* FD timeout in seconds */
int fd;
int read_ret, write_ret;
/**************************************************************************
Basic I/O
**************************************************************************/
int openPort(const char *portID);
int portRead(char *buf, int nbytes, int timeout);
int portWrite(const char * buf);
int LX200readOut(int timeout);
int Connect(const char* device);
void Disconnect(void);
/**************************************************************************
Diagnostics
**************************************************************************/
char ACK(void);
int testTelescope(void);
int testAP(void);
/**************************************************************************
Get Commands: store data in the supplied buffer. Return 0 on success or -1 on failure
**************************************************************************/
/* Get Double from Sexagisemal */
int getCommandSexa(double *value, const char *cmd);
/* Get String */
int getCommandString(char *data, const char* cmd);
/* Get Int */
int getCommandInt(int *value, const char* cmd);
/* Get tracking frequency */
int getTrackFreq(double * value);
/* Get site Latitude */
int getSiteLatitude(int *dd, int *mm);
/* Get site Longitude */
int getSiteLongitude(int *ddd, int *mm);
/* Get Calender data */
int getCalenderDate(char *date);
/* Get site Name */
int getSiteName(char *siteName, int siteNum);
/* Get Number of Bars */
int getNumberOfBars(int *value);
/* Get Home Search Status */
int getHomeSearchStatus(int *status);
/* Get OTA Temperature */
int getOTATemp(double * value);
/* Get time format: 12 or 24 */
int getTimeFormat(int *format);
/**************************************************************************
Set Commands
**************************************************************************/
/* Set Int */
int setCommandInt(int data, const char *cmd);
/* Set Sexigesimal */
int setCommandXYZ( int x, int y, int z, const char *cmd);
/* Common routine for Set commands */
int setStandardProcedure(char * writeData);
/* Set Slew Mode */
int setSlewMode(int slewMode);
/* Set Alignment mode */
int setAlignmentMode(unsigned int alignMode);
/* Set Object RA */
int setObjectRA(double ra);
/* set Object DEC */
int setObjectDEC(double dec);
/* Set Calender date */
int setCalenderDate(int dd, int mm, int yy);
/* Set UTC offset */
int setUTCOffset(double hours);
/* Set Track Freq */
int setTrackFreq(double trackF);
/* Set current site longitude */
int setSiteLongitude(double Long);
/* Set current site latitude */
int setSiteLatitude(double Lat);
/* Set Object Azimuth */
int setObjAz(double az);
/* Set Object Altitude */
int setObjAlt(double alt);
/* Set site name */
int setSiteName(char * siteName, int siteNum);
/* Set maximum slew rate */
int setMaxSlewRate(int slewRate);
/* Set focuser motion */
int setFocuserMotion(int motionType);
/* Set focuser speed mode */
int setFocuserSpeedMode (int speedMode);
/* Set minimum elevation limit */
int setMinElevationLimit(int min);
/* Set maximum elevation limit */
int setMaxElevationLimit(int max);
/**************************************************************************
Motion Commands
**************************************************************************/
/* Slew to the selected coordinates */
int Slew(void);
/* Synchronize to the selected coordinates and return the matching object if any */
int Sync(char *matchedObject);
/* Abort slew in all axes */
int abortSlew(void);
/* Move into one direction, two valid directions can be stacked */
int MoveTo(int direction);
/* Half movement in a particular direction */
int HaltMovement(int direction);
/* Select the tracking mode */
int selectTrackingMode(int trackMode);
/* Select Astro-Physics tracking mode */
int selectAPTrackingMode(int trackMode);
/**************************************************************************
Other Commands
**************************************************************************/
/* Ensures LX200 RA/DEC format is long */
int checkLX200Format(void);
/* Select a site from the LX200 controller */
int selectSite(int siteNum);
/* Select a catalog object */
int selectCatalogObject(int catalog, int NNNN);
/* Select a sub catalog */
int selectSubCatalog(int catalog, int subCatalog);
/**********************************************************************
* BASIC
**********************************************************************/
int Connect(const char *device)
{
fprintf(stderr, "Connecting to device %s\n", device);
if (openPort(device) < 0)
return -1;
else
return 0;
}
void Disconnect()
{
fprintf(stderr, "Disconnected.\n");
close(fd);
}
int testTelescope()
{
int i=0;
char ack[1] = { (char) 0x06 };
char MountAlign[64];
fprintf(stderr, "Testing telescope's connection...\n");
for (i=0; i < 2; i++)
{
write(fd, ack, 1);
read_ret = portRead(MountAlign, 1, LX200_TIMEOUT);
if (read_ret == 1)
return 0;
usleep(50000);
}
return -1;
}
int testAP()
{
int i=0;
char currentDate[64];
fprintf(stderr, "Testing telescope's connection...\n");
/* We need to test if the telescope is responding
/ We're going to request the calander date */
for (i=0; i < 2; i++)
{
if (!getCalenderDate(currentDate))
return 0;
usleep(50000);
}
return -1;
}
/**********************************************************************
* GET
**********************************************************************/
char ACK()
{
char ack[1] = { (char) 0x06 };
char MountAlign[2];
write_ret = write(fd, ack, 1);
if (write_ret < 0)
return -1;
read_ret = portRead(MountAlign, 1, LX200_TIMEOUT);
if (read_ret == 1)
return MountAlign[0];
else
return read_ret;
}
int getCommandSexa(double *value, const char * cmd)
{
char tempString[16];
tcflush(fd, TCIFLUSH);
if (portWrite(cmd) < 0)
return -1;
if ( (read_ret = portRead(tempString, -1, LX200_TIMEOUT)) < 1)
return read_ret;
tempString[read_ret - 1] = '\0';
if (f_scansexa(tempString, value))
{
fprintf(stderr, "unable to process [%s]\n", tempString);
return -1;
}
return 0;
}
int getCommandString(char *data, const char* cmd)
{
char * term;
if (portWrite(cmd) < 0)
return -1;
read_ret = portRead(data, -1, LX200_TIMEOUT);
if (read_ret < 1)
return read_ret;
term = strchr (data, '#');
if (term)
*term = '\0';
fprintf(stderr, "Requested data: %s\n", data);
return 0;
}
int getCalenderDate(char *date)
{
int dd, mm, yy;
int err;
if ( (err = getCommandString(date, "#:GC#")) )
return err;
/* Meade format is MM/DD/YY */
read_ret = sscanf(date, "%d%*c%d%*c%d", &mm, &dd, &yy);
if (read_ret < 3)
return -1;
/* We need to have in in YYYY/MM/DD format */
sprintf(date, "20%02d/%02d/%02d", yy, mm, dd);
return (0);
}
int getTimeFormat(int *format)
{
char tempString[16];
int tMode;
if (portWrite("#:Gc#") < 0)
return -1;
read_ret = portRead(tempString, -1, LX200_TIMEOUT);
if (read_ret < 1)
return read_ret;
tempString[read_ret-1] = '\0';
read_ret = sscanf(tempString, "(%d)", &tMode);
if (read_ret < 1)
return -1;
else
*format = tMode;
return 0;
}
/*int getUTCOffset()
{
char tempString[4];
int offSet;
portWrite("#:GG#");
read_ret = portRead(tempString, 4);
if (read_ret)
return -1;
tempString[3] = '\0';
sscanf(tempString, "%d", &offSet);
fprintf(stderr, "UTC Offset: %d\n", offSet);
return offSet;
}
int getMaxElevationLimit()
{
char tempString[16];
int limit;
portWrite("#:Go#");
read_ret = portRead(tempString, -1, LX200_TIMEOUT);
if (read_ret < 1)
return -1;
tempString[read_ret-1] = '\0';
sscanf(tempString, "%d", &limit);
fprintf(stderr, "Max elevation limit string is %s\n", tempString);
return limit;
}
int getMinElevationLimit()
{
char tempString[16];
int limit;
portWrite("#:Gh#");
read_ret = portRead(tempString, -1, LX200_TIMEOUT);
if (read_ret < 1)
return -1;
tempString[read_ret-1] = '\0';
sscanf(tempString, "%d", &limit);
fprintf(stderr, "Min elevation limit string is %s\n", tempString);
return limit;
}
*/
int getSiteName(char *siteName, int siteNum)
{
char * term;
switch (siteNum)
{
case 1:
if (portWrite("#:GM#") < 0)
return -1;
break;
case 2:
if (portWrite("#:GN#") < 0)
return -1;
break;
case 3:
if (portWrite("#:GO#") < 0)
return -1;
break;
case 4:
if (portWrite("#:GP#") < 0)
return -1;
break;
default:
return -1;
}
read_ret = portRead(siteName, -1, LX200_TIMEOUT);
if (read_ret < 1)
return read_ret;
siteName[read_ret - 1] = '\0';
term = strchr (siteName, ' ');
if (term)
*term = '\0';
term = strchr (siteName, '<');
if (term)
strcpy(siteName, "unused site");
fprintf(stderr, "Requested site name: %s\n", siteName);
return 0;
}
int getSiteLatitude(int *dd, int *mm)
{
char tempString[16];
if (portWrite("#:Gt#") < 0)
return -1;
read_ret = portRead(tempString, -1, LX200_TIMEOUT);
if (read_ret < 1)
return read_ret;
tempString[read_ret -1] = '\0';
if (sscanf (tempString, "%d%*c%d", dd, mm) < 2)
return -1;
fprintf(stderr, "Requested site latitude in String %s\n", tempString);
fprintf(stderr, "Requested site latitude %d:%d\n", *dd, *mm);
return 0;
}
int getSiteLongitude(int *ddd, int *mm)
{
char tempString[16];
if (portWrite("#:Gg#") < 0)
return -1;
read_ret = portRead(tempString, -1, LX200_TIMEOUT);
if (read_ret < 1)
return read_ret;
tempString[read_ret -1] = '\0';
if (sscanf (tempString, "%d%*c%d", ddd, mm) < 2)
return -1;
fprintf(stderr, "Requested site longitude in String %s\n", tempString);
fprintf(stderr, "Requested site longitude %d:%d\n", *ddd, *mm);
return 0;
}
int getTrackFreq(double *value)
{
float Freq;
char tempString[16];
if (portWrite("#:GT#") < 0)
return -1;
read_ret = portRead(tempString, -1, LX200_TIMEOUT);
if (read_ret < 1)
return read_ret;
tempString[read_ret] = '\0';
/*fprintf(stderr, "Telescope tracking freq str: %s\n", tempString);*/
if (sscanf(tempString, "%f#", &Freq) < 1)
return -1;
*value = (double) Freq;
/*fprintf(stderr, "Tracking frequency value is %f\n", Freq);*/
return 0;
}
int getNumberOfBars(int *value)
{
char tempString[128];
if (portWrite("#:D#") < 0)
return -1;
read_ret = portRead(tempString, -1, LX200_TIMEOUT);
if (read_ret < 0)
return read_ret;
*value = read_ret -1;
return 0;
}
int getHomeSearchStatus(int *status)
{
char tempString[16];
if (portWrite("#:h?#") < 0)
return -1;
read_ret = portRead(tempString, 1, LX200_TIMEOUT);
if (read_ret < 1)
return read_ret;
tempString[1] = '\0';
if (tempString[0] == '0')
*status = 0;
else if (tempString[0] == '1')
*status = 1;
else if (tempString[0] == '2')
*status = 1;
return 0;
}
int getOTATemp(double *value)
{
char tempString[16];
float temp;
if (portWrite("#:fT#") < 0)
return -1;
read_ret = portRead(tempString, -1, LX200_TIMEOUT);
if (read_ret < 1)
return read_ret;
tempString[read_ret - 1] = '\0';
if (sscanf(tempString, "%f", &temp) < 1)
return -1;
*value = (double) temp;
return 0;
}
int updateSkyCommanderCoord(double *ra, double *dec)
{
char coords[16];
char CR[1] = { (char) 0x0D };
float RA=0.0, DEC=0.0;
write(fd, CR, 1);
read_ret = portRead(coords, 16, LX200_TIMEOUT);
read_ret = sscanf(coords, " %g %g", &RA, &DEC);
if (read_ret < 2)
{
fprintf(stderr, "Error in Sky commander number format [%s], exiting.\n", coords);
return -1;
}
*ra = RA;
*dec = DEC;
return 0;
}
/**********************************************************************
* SET
**********************************************************************/
int setStandardProcedure(char * data)
{
char boolRet[2];
if (portWrite(data) < 0)
return -1;
read_ret = portRead(boolRet, 1, LX200_TIMEOUT);
if (read_ret < 1)
return read_ret;
if (boolRet[0] == '0')
{
fprintf(stderr, "%s Failed.\n", data);
return -1;
}
fprintf(stderr, "%s Successful\n", data);
return 0;
}
int setCommandInt(int data, const char *cmd)
{
char tempString[16];
snprintf(tempString, sizeof( tempString ), "%s%d#", cmd, data);
if (portWrite(tempString) < 0)
return -1;
return 0;
}
int setMinElevationLimit(int min)
{
char tempString[16];
snprintf(tempString, sizeof( tempString ), "#:Sh%02d#", min);
return (setStandardProcedure(tempString));
}
int setMaxElevationLimit(int max)
{
char tempString[16];
snprintf(tempString, sizeof( tempString ), "#:So%02d*#", max);
return (setStandardProcedure(tempString));
}
int setMaxSlewRate(int slewRate)
{
char tempString[16];
if (slewRate < 2 || slewRate > 8)
return -1;
snprintf(tempString, sizeof( tempString ), "#:Sw%d#", slewRate);
return (setStandardProcedure(tempString));
}
int setObjectRA(double ra)
{
int h, m, s;
char tempString[16];
getSexComponents(ra, &h, &m, &s);
snprintf(tempString, sizeof( tempString ), "#:Sr %02d:%02d:%02d#", h, m, s);
IDLog("Set Object RA String %s\n", tempString);
return (setStandardProcedure(tempString));
}
int setObjectDEC(double dec)
{
int d, m, s;
char tempString[16];
getSexComponents(dec, &d, &m, &s);
/* case with negative zero */
if (!d && dec < 0)
snprintf(tempString, sizeof( tempString ), "#:Sd -%02d:%02d:%02d#", d, m, s);
else
snprintf(tempString, sizeof( tempString ), "#:Sd %+03d:%02d:%02d#", d, m, s);
IDLog("Set Object DEC String %s\n", tempString);
return (setStandardProcedure(tempString));
}
int setCommandXYZ(int x, int y, int z, const char *cmd)
{
char tempString[16];
snprintf(tempString, sizeof( tempString ), "%s %02d:%02d:%02d#", cmd, x, y, z);
return (setStandardProcedure(tempString));
}
int setAlignmentMode(unsigned int alignMode)
{
fprintf(stderr , "Set alignment mode %d\n", alignMode);
switch (alignMode)
{
case LX200_ALIGN_POLAR:
if (portWrite("#:AP#") < 0)
return -1;
break;
case LX200_ALIGN_ALTAZ:
if (portWrite("#:AA#") < 0)
return -1;
break;
case LX200_ALIGN_LAND:
if (portWrite("#:AL#") < 0)
return -1;
break;
}
return 0;
}
int setCalenderDate(int dd, int mm, int yy)
{
char tempString[32];
char dumpPlanetaryUpdateString[64];
char boolRet[2];
yy = yy % 100;
snprintf(tempString, sizeof( tempString ), "#:SC %02d/%02d/%02d#", mm, dd, yy);
if (portWrite(tempString) < 0)
return -1;
read_ret = portRead(boolRet, 1, LX200_TIMEOUT);
if (read_ret < 1)
return read_ret;
boolRet[1] = '\0';
if (boolRet[0] == '0')
return -1;
/* Read dumped data */
portRead(dumpPlanetaryUpdateString, -1, LX200_TIMEOUT);
portRead(dumpPlanetaryUpdateString, -1, 5);
return 0;
}
int setUTCOffset(double hours)
{
char tempString[16];
/*TODO add fractions*/
snprintf(tempString, sizeof( tempString ), "#:SG %+03d#", (int) hours);
fprintf(stderr, "UTC string is %s\n", tempString);
return (setStandardProcedure(tempString));
}
int setSiteLongitude(double Long)
{
int d, m, s;
char tempString[32];
getSexComponents(Long, &d, &m, &s);
snprintf(tempString, sizeof( tempString ), "#:Sg%03d:%02d#", d, m);
return (setStandardProcedure(tempString));
}
int setSiteLatitude(double Lat)
{
int d, m, s;
char tempString[32];
getSexComponents(Lat, &d, &m, &s);
snprintf(tempString, sizeof( tempString ), "#:St%+03d:%02d:%02d#", d, m, s);
return (setStandardProcedure(tempString));
}
int setObjAz(double az)
{
int d,m,s;
char tempString[16];
getSexComponents(az, &d, &m, &s);
snprintf(tempString, sizeof( tempString ), "#:Sz%03d:%02d#", d, m);
return (setStandardProcedure(tempString));
}
int setObjAlt(double alt)
{
int d, m, s;
char tempString[16];
getSexComponents(alt, &d, &m, &s);
snprintf(tempString, sizeof( tempString ), "#:Sa%+02d*%02d#", d, m);
return (setStandardProcedure(tempString));
}
int setSiteName(char * siteName, int siteNum)
{
char tempString[16];
switch (siteNum)
{
case 1:
snprintf(tempString, sizeof( tempString ), "#:SM %s#", siteName);
break;
case 2:
snprintf(tempString, sizeof( tempString ), "#:SN %s#", siteName);
break;
case 3:
snprintf(tempString, sizeof( tempString ), "#:SO %s#", siteName);
break;
case 4:
snprintf(tempString, sizeof( tempString ), "#:SP %s#", siteName);
break;
default:
return -1;
}
return (setStandardProcedure(tempString));
}
int setSlewMode(int slewMode)
{
switch (slewMode)
{
case LX200_SLEW_MAX:
if (portWrite("#:RS#") < 0)
return -1;
break;
case LX200_SLEW_FIND:
if (portWrite("#:RM#") < 0)
return -1;
break;
case LX200_SLEW_CENTER:
if (portWrite("#:RC#") < 0)
return -1;
break;
case LX200_SLEW_GUIDE:
if (portWrite("#:RG#") < 0)
return -1;
break;
default:
break;
}
return 0;
}
int setFocuserMotion(int motionType)
{
switch (motionType)
{
case LX200_FOCUSIN:
if (portWrite("#:F+#") < 0)
return -1;
break;
case LX200_FOCUSOUT:
if (portWrite("#:F-#") < 0)
return -1;
break;
}
return 0;
}
int setFocuserSpeedMode (int speedMode)
{
switch (speedMode)
{
case LX200_HALTFOCUS:
if (portWrite("#:FQ#") < 0)
return -1;
break;
case LX200_FOCUSSLOW:
if (portWrite("#:FS#") < 0)
return -1;
break;
case LX200_FOCUSMEDIUM:
if (portWrite("#:F3#") < 0)
return -1;
break;
case LX200_FOCUSFAST:
if (portWrite("#:FF#") < 0)
return -1;
break;
}
return 0;
}
int setTrackFreq(double trackF)
{
char tempString[16];
snprintf(tempString, sizeof( tempString ), "#:ST %04.1f#", trackF);
return (setStandardProcedure(tempString));
}
/**********************************************************************
* Misc
*********************************************************************/
int Slew()
{
char slewNum[2];
char errorMsg[128];
if (portWrite("#:MS#") < 0)
return -1;
read_ret = portRead(slewNum, 1, LX200_TIMEOUT);
if (read_ret < 1)
return read_ret;
slewNum[1] = '\0';
if (slewNum[0] == '0')
return 0;
read_ret = portRead(errorMsg, -1, LX200_TIMEOUT);
if (read_ret < 1)
return read_ret;
if (slewNum[0] == '1')
return 1;
else return 2;
}
int MoveTo(int direction)
{
switch (direction)
{
case LX200_NORTH:
portWrite("#:Mn#");
break;
case LX200_WEST:
portWrite("#:Mw#");
break;
case LX200_EAST:
portWrite("#:Me#");
break;
case LX200_SOUTH:
portWrite("#:Ms#");
break;
default:
break;
}
return 0;
}
int HaltMovement(int direction)
{
switch (direction)
{
case LX200_NORTH:
if (portWrite("#:Qn#") < 0)
return -1;
break;
case LX200_WEST:
if (portWrite("#:Qw#") < 0)
return -1;
break;
case LX200_EAST:
if (portWrite("#:Qe#") < 0)
return -1;
break;
case LX200_SOUTH:
if (portWrite("#:Qs#") < 0)
return -1;
break;
case LX200_ALL:
if (portWrite("#:Q#") < 0)
return -1;
break;
default:
return -1;
break;
}
return 0;
}
int abortSlew()
{
if (portWrite("#:Q#") < 0)
return -1;
return 0;
}
int Sync(char *matchedObject)
{
portWrite("#:CM#");
read_ret = portRead(matchedObject, -1, LX200_TIMEOUT);
if (read_ret < 1)
return read_ret;
matchedObject[read_ret-1] = '\0';
/* Sleep 10ms before flushing. This solves some issues with LX200 compatible devices. */
usleep(10000);
tcflush(fd, TCIFLUSH);
return 0;
}
int selectSite(int siteNum)
{
switch (siteNum)
{
case 1:
if (portWrite("#:W1#") < 0)
return -1;
break;
case 2:
if (portWrite("#:W2#") < 0)
return -1;
break;
case 3:
if (portWrite("#:W3#") < 0)
return -1;
break;
case 4:
if (portWrite("#:W4#") < 0)
return -1;
break;
default:
return -1;
break;
}
return 0;
}
int selectCatalogObject(int catalog, int NNNN)
{
char tempString[16];
switch (catalog)
{
case LX200_STAR_C:
snprintf(tempString, sizeof( tempString ), "#:LS%d#", NNNN);
break;
case LX200_DEEPSKY_C:
snprintf(tempString, sizeof( tempString ), "#:LC%d#", NNNN);
break;
case LX200_MESSIER_C:
snprintf(tempString, sizeof( tempString ), "#:LM%d#", NNNN);
break;
default:
return -1;
}
if (portWrite(tempString) < 0)
return -1;
return 0;
}
int selectSubCatalog(int catalog, int subCatalog)
{
char tempString[16];
switch (catalog)
{
case LX200_STAR_C:
snprintf(tempString, sizeof( tempString ), "#:LsD%d#", subCatalog);
break;
case LX200_DEEPSKY_C:
snprintf(tempString, sizeof( tempString ), "#:LoD%d#", subCatalog);
break;
case LX200_MESSIER_C:
return 1;
default:
return 0;
}
return (setStandardProcedure(tempString));
}
int checkLX200Format()
{
char tempString[16];
if (portWrite("#:GR#") < 0)
return -1;
read_ret = portRead(tempString, -1, LX200_TIMEOUT);
if (read_ret < 1)
return read_ret;
tempString[read_ret - 1] = '\0';
/* Short */
if (tempString[5] == '.')
if (portWrite("#:U#") < 0)
return -1;
return 0;
}
int selectTrackingMode(int trackMode)
{
switch (trackMode)
{
case LX200_TRACK_DEFAULT:
fprintf(stderr, "Setting tracking mode to sidereal.\n");
if (portWrite("#:TQ#") < 0)
return -1;
break;
case LX200_TRACK_LUNAR:
fprintf(stderr, "Setting tracking mode to LUNAR.\n");
if (portWrite("#:TL#") < 0)
return -1;
break;
case LX200_TRACK_MANUAL:
fprintf(stderr, "Setting tracking mode to CUSTOM.\n");
if (portWrite("#:TM#") < 0)
return -1;
break;
default:
return -1;
break;
}
return 0;
}
int selectAPTrackingMode(int trackMode)
{
switch (trackMode)
{
/* Lunar */
case 0:
fprintf(stderr, "Setting tracking mode to lunar.\n");
if (portWrite("#:RT0#") < 0)
return -1;
break;
/* Solar */
case 1:
fprintf(stderr, "Setting tracking mode to solar.\n");
if (portWrite("#:RT1#") < 0)
return -1;
break;
/* Sidereal */
case 2:
fprintf(stderr, "Setting tracking mode to sidereal.\n");
if (portWrite("#:RT2#") < 0)
return -1;
break;
/* Zero */
case 3:
fprintf(stderr, "Setting tracking mode to zero.\n");
if (portWrite("#:RT9#") < 0)
return -1;
break;
default:
return -1;
break;
}
return 0;
}
/**********************************************************************
* Comm
**********************************************************************/
int openPort(const char *portID)
{
struct termios ttyOptions;
if ( (fd = open(portID, O_RDWR)) == -1)
return -1;
memset(&ttyOptions, 0, sizeof(ttyOptions));
tcgetattr(fd, &ttyOptions);
/* Control options
charecter size */
ttyOptions.c_cflag &= ~CSIZE;
/* 8 bit, enable read */
ttyOptions.c_cflag |= CREAD | CLOCAL | CS8;
/* no parity */
ttyOptions.c_cflag &= ~PARENB;
/* set baud rate */
cfsetispeed(&ttyOptions, B9600);
cfsetospeed(&ttyOptions, B9600);
/* set input/output flags */
ttyOptions.c_iflag = IGNBRK;
/* no software flow control */
ttyOptions.c_iflag &= ~(IXON|IXOFF|IXANY);
/* Read at least one byte */
ttyOptions.c_cc[VMIN] = 1;
ttyOptions.c_cc[VTIME] = 5;
/* Misc. */
ttyOptions.c_lflag = 0;
ttyOptions.c_oflag = 0;
/* set attributes */
tcsetattr(fd, TCSANOW, &ttyOptions);
/* flush the channel */
tcflush(fd, TCIOFLUSH);
return (fd);
}
int portWrite(const char * buf)
{
int nbytes, totalBytesWritten;
int bytesWritten = 0;
nbytes = totalBytesWritten = strlen(buf);
while (nbytes > 0)
{
bytesWritten = write(fd, buf, nbytes);
if (bytesWritten < 0)
return -1;
buf += bytesWritten;
nbytes -= bytesWritten;
}
/* Returns the # of bytes written */
return (totalBytesWritten);
}
int portRead(char *buf, int nbytes, int timeout)
{
int bytesRead = 0;
int totalBytesRead = 0;
int err;
/* Loop until encountring the '#' char */
if (nbytes == -1)
{
for (;;)
{
if ( (err = LX200readOut(timeout)) )
return err;
bytesRead = read(fd, buf, 1);
if (bytesRead < 0 )
return -1;
if (bytesRead)
totalBytesRead++;
if (*buf == '#')
return totalBytesRead;
buf += bytesRead;
}
}
while (nbytes > 0)
{
if ( (err = LX200readOut(timeout)) )
return err;
bytesRead = read(fd, buf, nbytes);
if (bytesRead < 0 )
return -1;
buf += bytesRead;
totalBytesRead++;
nbytes -= bytesRead;
}
return totalBytesRead;
}
int LX200readOut(int timeout)
{
struct timeval tv;
fd_set readout;
int retval;
FD_ZERO(&readout);
FD_SET(fd, &readout);
/* wait for 'timeout' seconds */
tv.tv_sec = timeout;
tv.tv_usec = 0;
/* Wait till we have a change in the fd status */
retval = select (fd+1, &readout, NULL, NULL, &tv);
/* Return 0 on successful fd change */
if (retval > 0)
return 0;
/* Return -1 due to an error */
else if (retval == -1)
return retval;
/* Return -2 if time expires before anything interesting happens */
else
return -2;
}