source: BAORadio/libindi/libindi/drivers/telescope/temmadriver.c @ 642

Last change on this file since 642 was 642, checked in by frichard, 12 years ago

-Alignement des antennes
-Version 0.0.9 de libindi

File size: 21.2 KB
Line 
1#if 0
2        Temma INDI driver
3        Copyright (C) 2004 Francois Meyer (dulle @ free.fr)
4        Remi Petitdemange for the temma protocol
5  Reference site is http://dulle.free.fr/alidade/indi.php
6
7        This library is free software; you can redistribute it and/or
8        modify it under the terms of the GNU Lesser General Public
9        License as published by the Free Software Foundation; either
10        version 2.1 of the License, or (at your option) any later version.
11
12        This library is distributed in the hope that it will be useful,
13        but WITHOUT ANY WARRANTY; without even the implied warranty of
14        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15        Lesser General Public License for more details.
16
17        You should have received a copy of the GNU Lesser General Public
18        License along with this library; if not, write to the Free Software
19        Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
21#endif
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <stdarg.h>
27#include <math.h>
28#include <sys/time.h>
29#include <unistd.h>
30#include <fcntl.h>
31#include <termios.h>
32#include <time.h>
33
34#include <config.h>
35
36#include <libnova.h>
37
38#include "indicom.h"
39#include "indidevapi.h"
40#include "eventloop.h"
41#include "indicom.h"
42#include "temmadriver.h"
43
44
45        char errormes[][128]={
46                "I/O Timeout",
47                "Error reading from io port",
48                "Error writing to io port",
49                "Unrecognized message"
50        };
51
52char answer[32];
53int fd;
54int read_ret, write_ret;
55unsigned char buffer[256];
56unsigned char buffer2[256];
57
58
59#if 1
60/* Initlization routine */
61static void mountInit()
62{
63        static int inited;              /* set once mountInit is called */
64
65        if (inited)
66                return;
67
68        /* setting default comm port */ 
69        PortT->text = realloc(PortT->text, 10);
70        TemmaNoteT[0].text = realloc( TemmaNoteT[0].text, 64);
71        TemmaNoteT[1].text = realloc( TemmaNoteT[1].text, 64);
72       
73        if (!PortT->text || !TemmaNoteT[0].text || !TemmaNoteT[1].text){
74                fprintf(stderr,"Memory allocation error");
75                return;
76        }
77        strcpy(PortT->text, "/dev/ttyS0");
78        strcpy(TemmaNoteT[0].text, "Experimental Driver");
79        strcpy(TemmaNoteT[1].text, "http://dulle.free.fr/alidade/indi.php");
80
81        inited = 1;
82}
83#endif
84
85void ISGetProperties (const char *dev) {
86        if (dev && strcmp (mydev, dev))
87                return;
88
89        mountInit();
90
91        IDDefSwitch (&powSw, NULL);
92        IDDefNumber (&eqTemma, NULL);
93        IDDefNumber (&eqNum, NULL);
94        IDDefSwitch (&OnCoordSetSw, NULL);
95        IDDefSwitch (&abortSlewSw, NULL);
96        IDDefText   (&TemmaNoteTP, NULL);
97        IDDefSwitch (&RAmotorSw, NULL);
98        IDDefSwitch (&trackmodeSw, NULL);
99        IDDefText (&Port, NULL);
100        IDDefText (&TemmaVersion, NULL);
101        IDDefNumber (&Time, NULL);
102        IDDefNumber (&SDTime, NULL);
103        IDDefNumber (&cometNum, NULL);
104        IDDefNumber (&geoNum, NULL);
105}
106
107void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n) 
108{
109  INDI_UNUSED(dev);
110  INDI_UNUSED(name);
111  INDI_UNUSED(sizes);
112  INDI_UNUSED(blobsizes);
113  INDI_UNUSED(blobs);
114  INDI_UNUSED(formats);
115  INDI_UNUSED(names);
116  INDI_UNUSED(n);
117}
118void ISSnoopDevice (XMLEle *root) 
119{
120  INDI_UNUSED(root);
121}
122
123void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) 
124{
125
126        INDI_UNUSED(names);
127        INDI_UNUSED(n);
128
129        if (strcmp (dev, mydev))
130                return;
131
132        if (!strcmp (name, Port.name)) {
133                IUSaveText(PortT, texts[0]);
134                Port.s = IPS_OK;
135                IDSetText (&Port, NULL);
136        }
137        return;
138}
139
140/* client is sending us a new value for a Numeric vector property */
141void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) {
142        /* ignore if not ours */
143        if (strcmp (dev, mydev))
144                return;
145
146        if (!strcmp (name, eqNum.name)) {
147                /* new equatorial target coords */
148                /*double newra = 0, newdec = 0;*/
149                int i, nset;
150
151                /* Check power, if it is off, then return */
152                if (power[0].s != ISS_ON)
153                {
154                        eqNum.s = IPS_IDLE;
155                        IDSetNumber(&eqNum, "Power is off");
156                        return;
157                }
158
159                for (nset = i = 0; i < n; i++) {
160                        /* Find numbers with the passed names in the eqNum property */
161                        INumber *eqp = IUFindNumber (&eqNum, names[i]);
162
163                        /* If the number found is Right ascension (eq[0]) then process it */
164                        if (eqp == &eq[0])
165                        {
166                                currentRA = (values[i]);
167                                nset += currentRA >= 0 && currentRA <= 24;
168                        }
169                        /* Otherwise, if the number found is Declination (eq[1]) then process it */ 
170                        else if (eqp == &eq[1]) {
171                                currentDec = (values[i]);
172                                nset += currentDec >= -90 && currentDec <= 90;
173                        }
174                } /* end for */
175
176                /* Did we process the two numbers? */
177                if (nset == 2) {
178                        /*char r[32], d[32];*/
179
180                        /* Set the mount state to BUSY */
181                        eqNum.s = IPS_BUSY;
182
183                        if (SLEWSW==ISS_ON || TRACKSW==ISS_ON){
184                                IDSetNumber(&eqNum, "Moving to RA Dec %f %f", currentRA,
185                                                currentDec);
186                                do_TemmaGOTO();
187                        }
188
189                        if (SYNCSW==ISS_ON){
190                                IDSetNumber(&eqNum, "Syncing to RA Dec %f %f", currentRA, currentDec);
191                                set_TemmaCurrentpos();
192                        }
193                        eqNum.s = IPS_OK;
194                        IDSetNumber(&eqNum, "Synced");
195                }
196                /* We didn't process the two number correctly, report an error */
197                else {
198                        /* Set property state to idle */
199                        eqNum.s = IPS_IDLE;
200
201                        IDSetNumber(&eqNum, "RA or Dec absent or bogus.");
202                }
203        return;
204        }
205}
206
207/* client is sending us a new value for a Switch property */
208void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
209{
210        ISwitch *sp;
211
212        /* ignore if not ours */
213        if (strcmp (dev, mydev))
214                return;
215
216        if (!strcmp (name, powSw.name)) {
217                sp = IUFindSwitch (&powSw, names[0]);
218                if (!sp)
219                        return;
220
221                fprintf(stderr,"new state %s\n",names[0]);
222
223                sp->s = states[0];
224                if (!strcmp(names[0],"CONNECT")) {
225                        connectMount();
226                }               
227                if (!strcmp(names[0],"DISCONNECT")) {
228                        disconnectMount();
229                }               
230        }
231
232        if (!strcmp (name, abortSlewSw.name)) {
233                if (POWSW){
234                        TemmaabortSlew(); 
235                        IDSetSwitch (&abortSlewSw, "Abort slew");
236                }
237                else {
238                        IDSetSwitch (&abortSlewSw, "Power is off");
239                }
240        }
241
242        if (!strcmp (name, RAmotorSw.name)) {
243                if (POWSW){
244                        sp = IUFindSwitch (&RAmotorSw, names[0]);
245                        if (!sp)
246                                return;
247
248                        fprintf(stderr,"new state %s\n",names[0]);
249
250                        sp->s = states[0];
251
252                        RAmotorSw.s = IPS_BUSY;
253                        if (!strcmp(names[0],"RUN")) {
254                                set_TemmaStandbyState(0);
255                        }
256
257                        if (!strcmp(names[0],"STOP")) {
258                                set_TemmaStandbyState(1);
259                        }       
260
261                        if(get_TemmaStandbyState(buffer)){
262                                RAmotorSw.s = IPS_IDLE;
263                                IDSetSwitch (&RAmotorSw, "Error writing to port");
264                                return;
265                        }
266                }
267                else {
268                        IDSetSwitch (&RAmotorSw, "Power is off");
269                }
270        }
271
272        if (!strcmp (name, OnCoordSetSw.name)) {
273                if (POWSW){
274                        IUResetSwitch(&OnCoordSetSw);
275                        sp = IUFindSwitch (&OnCoordSetSw, names[0]);
276                        if (!sp)
277                                return;
278
279                        fprintf(stderr,"new state %s\n",names[0]);
280
281                        sp->s = states[0];
282
283                        IUResetSwitch(&OnCoordSetSw);
284                        IUUpdateSwitch(&OnCoordSetSw, states, names, n);
285                        /*                          currentSet = getOnSwitch(&OnCoordSetSw); */
286                        OnCoordSetSw.s = IPS_OK;
287                        IDSetSwitch(&OnCoordSetSw, NULL);
288                }
289                else {
290                        IDSetSwitch (&OnCoordSetSw, "Power is off");
291                }
292        }
293}
294
295double calcLST(char *strlst){
296        double jd,gmst,lst;
297
298        jd = ln_get_julian_from_sys();
299        gmst = ln_get_mean_sidereal_time(jd);
300
301        lst=(gmst-longitude)/15;       
302
303        lst=(lst/24-(int)(lst/24))*24;
304
305        if(lst>=24) 
306                lst-=24;
307        sprintf(strlst,"%.2d%.2d%.2d", (int)lst,
308                        ((int)(lst*60))%60,
309                        ((int)(lst*3600))%60);
310        currentLST=lst;
311        IDSetNumber (&SDTime, NULL);
312        IDSetNumber (&Time, NULL);
313       
314        return 0;
315}
316
317#if 1
318/* update the mount over time */
319void readMountcurrentpos (void *p)
320{
321        INDI_UNUSED(p);
322
323        char result[32];
324
325        if(POWSW){
326                get_TemmaCurrentpos(result);
327                calcLST(result);
328
329                /* This is a temporary workaround to allow
330                   clients with only one eq property to work */
331                currentRA=temmaRA;
332                currentDec=temmaDec;
333
334                /* again */
335                IEAddTimer (POLLMS, readMountcurrentpos, NULL);
336        }
337}
338#endif
339
340static void connectMount () {
341        fprintf(stderr,"opening mount port %s\n",PortT->text);
342        if (power[0].s == ISS_ON){
343                if (Port.s != IPS_OK){
344                        powSw.s = IPS_IDLE;
345                        power[0].s = ISS_OFF;
346
347                        IDSetSwitch (&powSw, "Port not set.");
348                        return;
349                }
350                else {
351                        if (TemmaConnect(PortT->text)==0){
352                                IDSetText (&Port, "Port is opened.");
353                                if( !get_TemmaVERSION(buffer)){
354                                        powSw.s = IPS_OK;
355                                        power[0].s = ISS_ON;
356                                        power[1].s = ISS_OFF;
357                                        snprintf(buffer2,sizeof( buffer2 ),"%s",buffer+4);
358
359                                        IDSetText(&TemmaVersion , "Temma version set");
360                                        TemmaVersionT->text = realloc(TemmaVersionT->text, strlen(buffer2)+1);
361                                        if (!TemmaVersionT->text){
362                                                fprintf(stderr,"Memory allocation error");
363                                                return;
364                                        }
365                                        IDSetSwitch (&powSw, "Mount is ready");
366                                        IDSetSwitch (&powSw, VERSION);
367
368                                        strcpy(TemmaVersionT->text, buffer2);
369                                        TemmaVersion.s = IPS_OK; 
370                                        IDSetText (&TemmaVersion, NULL);
371                                        IDLog("%s", buffer2);
372                                        /* start timer to read mount coords */
373                                        IEAddTimer (POLLMS, readMountcurrentpos, NULL);
374                                }
375                                else {
376                                        powSw.s = IPS_IDLE;
377                                        power[0].s = ISS_OFF;
378                                        power[1].s = ISS_ON;
379                                        IDSetText(&Port , "Com error");
380                                        IDSetSwitch (&powSw, "Port not set.");
381                                }
382
383                                if(get_TemmaStandbyState(answer)){
384                                        IDSetSwitch (&RAmotorSw, "Error writing to port");
385                                        return;
386                                }
387                        }
388                        else {
389                                powSw.s = IPS_IDLE;
390                                power[0].s = ISS_OFF;
391                                power[1].s = ISS_ON;
392
393                                IDSetSwitch (&powSw, "Failed to open port.");
394                        }
395                }
396        }
397}
398
399static void disconnectMount () {
400        fprintf(stderr,"closing mount port %s\n",PortT->text);
401        if (power[1].s == ISS_ON){
402                if (Port.s != IPS_OK){
403                        powSw.s = IPS_IDLE;
404                        power[0].s = ISS_OFF;
405
406                        IDSetSwitch (&powSw, "Port not set.");
407                        return;
408                }
409                else {
410                        TemmaDisconnect();
411                        powSw.s = IPS_IDLE;
412                        power[0].s = ISS_OFF;
413
414                        IDSetSwitch (&powSw, "Port is closed.");
415                }
416        }
417        else {
418                fprintf(stderr, "Already disconnected \n");
419        }
420}
421
422int TemmaConnect(const char *device) {
423        fprintf(stderr, "Connecting to device %s\n", device);
424
425        if (openPort(device) < 0){
426                fprintf(stderr, "Error connecting to device %s\n", device);
427                return -1;
428        }
429        else{
430                return 0;
431        }
432}
433
434int TemmaDisconnect() {
435        fprintf(stderr, "Disconnected.\n");
436        close(fd);
437       
438        return 0;
439}
440
441int set_CometTracking(int RArate, int DECrate){
442#if 0
443        Set Comet Tracking
444        LM+/-99999,+/-9999
445        RA : Adjust Sidereal time by seconds per Day   
446
447        DEC : Adjust DEC tracking by Minutes Per Day                   
448        valeur DEC min=-600 /max=+600 (+/-10 deg / jour)
449
450        Example:
451        LM+120,+30 would slow the RA speed by 86164/86284 and           
452        the Dec would track at 30 Minutes a day.
453        To stop tracking either send a LM0,0 (or a PS
454        sauf erreur on constate en faite l inverse en RA
455        retour Vsideral => LM0,0 ou LM+0,+0
456#endif
457        char local_buffer[16];
458
459        if (RArate<-21541){
460        RArate=-21541;
461        }
462
463        if (RArate>21541){
464        RArate=21541;
465        }
466
467        if (DECrate<-600){
468        DECrate=-600;
469        }
470
471        if (DECrate>600){
472        DECrate=600;
473        }
474
475        snprintf(local_buffer, sizeof( local_buffer ), "%+6d,%+5d", RArate, DECrate);
476        set_TemmaCometTracking(local_buffer);
477       
478        return 0;
479}
480
481int TemmaabortSlew() {
482        if (portWrite("PS") < 0)
483                return -1;
484
485        return 0;
486}
487
488int do_TemmaGOTO() {
489        /* Temma Sync */
490        char command[16];
491        char sign;
492        double dec;
493
494        calcLST(buffer);
495        set_TemmaLST(buffer);
496
497        dec=fabs(currentDec);
498        if (currentDec>0){
499                sign='+';
500        }
501        else {
502                sign='-';
503        }
504
505        snprintf(buffer, sizeof(buffer),"%.2d%.2d%.2d%c%.2d%.2d%.1d",
506                        (int)currentRA,(int)(currentRA*(double)60)%60,((int)(currentRA*(double)6000))%100,sign,
507                        (int)dec,(int)(dec*(double)60)%60,((int)(dec*(double)600))%10);
508        fprintf(stderr,"Goto %s\n", buffer);
509
510        snprintf(command,14,"P%s",buffer);
511        buffer[14]=0;
512        fprintf(stderr,"Goto command:%s\n", command);
513        portWrite(command);
514
515        portRead(buffer,-1,TEMMA_TIMEOUT);
516        if(command[0]=='R'){
517                return 0;
518        }
519        else
520                return -1;
521}
522
523int extractRA(char *buf){
524        int r,h,m,s;
525        /*double dra;*/
526
527        r=atoi(buf);
528        h=r/10000;
529        m=r/100-100*h;
530        s=(r%100)*.6;
531        temmaRA=((double)h+((double)m + (double)s/60)/60);
532        IDSetNumber (&eqTemma, NULL);
533        /*      fprintf(stderr,"extractRA: %s %d %d %d %d %lf\n",buf,r,h,m,s,dra);*/
534        return 0;
535}
536
537int extractDEC(char *buf){
538        int dec,d,m,s;
539        /*double ddec;*/
540
541        dec=atoi(buf+1);
542        d=dec/1000;
543        m=dec/10-100*d;
544        s=(dec%10)*6;
545        temmaDec=((double)d+((double)m + (double)s/60)/60);
546        if (*buf=='-') 
547                temmaDec*=-1;
548
549        IDSetNumber (&eqTemma, NULL);
550
551
552        /*      fprintf(stderr,"extractDEC: %s %d %d %d %d %lf\n",buf,dec,d,m,s,ddec);*/
553        return 0;
554}
555
556
557int get_TemmaCurrentpos(char *local_buffer){
558        char buf[16];
559
560        if (portWrite("E") < 0)
561                return -1;
562
563        if(portRead(local_buffer,-1,TEMMA_TIMEOUT)==SUCCESS){
564                if(strstr(local_buffer, "E")==local_buffer){
565                        strncpy(buf,local_buffer+1,6);
566                        buf[6]=0;
567                        extractRA(buf);
568
569                        strncpy(buf,local_buffer+7,6);
570                        buf[6]=0;
571                        extractDEC(buf);
572                        return 0;
573                }
574                else {
575                        return -1;
576                }
577        }
578       
579        return 0;
580}
581
582int set_TemmaCurrentpos(void) {
583        /* Temma Sync */
584        char buf[16], sign;
585        double dec;
586
587        calcLST(buf);
588        set_TemmaLST(buf);
589        portWrite("Z");
590        calcLST(buf);
591        set_TemmaLST(buf);
592
593        dec=fabs(currentDec);
594        if (currentDec>0){
595                sign='+';
596        }
597        else {
598                sign='-';
599        }
600
601        sprintf(buffer,"%.2d%.2d%.2d%c%.2d%.2d%.1d",
602                        (int)currentRA,(int)(currentRA*(double)60)%60,((int)(currentRA*(double)6000))%100,sign,
603                        (int)dec,(int)(dec*(double)60)%60,((int)(dec*(double)600))%10);
604        fprintf(stderr,"sync to %s %f %f\n", buffer,currentRA,dec);
605
606        snprintf(buf, sizeof(buf), "D%s",buffer);
607        buf[13]=0;
608        portWrite(buf);
609        *buffer=0;
610
611        portRead(buffer,-1,TEMMA_TIMEOUT);
612        if(buffer[0]=='R'){
613                return 0;
614        }
615        else{
616                return -1;
617        }
618}
619
620int do_TemmaSLEW(char mode){
621        /*char command[16];*/
622
623        sprintf(buffer,"M%c",mode); /* see bit definition in Temmadriver.h */
624
625        if (portWrite(buffer) < 0)
626                return -1;
627       
628        return 0;
629}
630
631int get_TemmaVERSION(char *local_buffer){
632        int err;
633
634        if ((err=portWrite("v")) < 0){
635                return err;
636        }
637
638        portRead(local_buffer,-1,TEMMA_TIMEOUT);
639        if(strstr(local_buffer, "ver")==local_buffer){
640                return 0;
641        }
642        else
643                return EREAD;
644}
645
646int get_TemmaGOTOstatus(char *local_buffer){
647        /*
648           0 no ongoing goto
649           1 ongoing Goto
650           -1 error
651         */
652        if (portWrite("s") < 0)
653                return -1;
654
655        portRead(local_buffer,-1,TEMMA_TIMEOUT);
656        if(strstr(local_buffer, "s")==local_buffer){
657                return 0;
658        }
659        else
660                return -1;
661}
662
663int get_TemmaBOTHcorrspeed(char *local_buffer){
664        if (portWrite("lg") < 0)
665                return -1;
666        portRead(local_buffer,-1,TEMMA_TIMEOUT);
667        if(strstr(local_buffer, "lg")==local_buffer){
668                return 0;
669        }
670        else
671                return -1;
672}
673
674int get_TemmaDECcorrspeed(char *local_buffer){
675        if (portWrite("lb") < 0)
676                return -1;
677        portRead(local_buffer,-1,TEMMA_TIMEOUT);
678        if(strstr(local_buffer, "lb")==local_buffer){
679                return 0;
680        }
681        else
682                return -1;
683}
684
685int set_TemmaDECcorrspeed(char *local_buffer){
686        char command[16];
687
688        snprintf(command, 4, "LB%s",local_buffer);
689
690        if (portWrite(command) < 0)
691                return -1;
692        return 0;
693}
694
695int get_TemmaRAcorrspeed(char *local_buffer){
696        if (portWrite("la") < 0)
697                return -1;
698
699        portRead(local_buffer,-1,TEMMA_TIMEOUT);
700        if(strstr(local_buffer, "la")==local_buffer){
701                return 0;
702        }
703        else
704                return -1;
705}
706
707int set_TemmaRAcorrspeed(char *local_buffer){
708        char command[16];
709
710        snprintf(command, 4,"LA%s",local_buffer);
711
712        if (portWrite(command) < 0)
713                return -1;
714        return 0;
715}
716
717int get_TemmaLatitude(char *local_buffer){
718        if (portWrite("i") < 0)
719                return -1;
720        portRead(local_buffer,-1,TEMMA_TIMEOUT);
721        if(local_buffer[0]=='i'){
722                return 0;
723        }
724        else 
725                return -1;
726}
727
728int set_TemmaLatitude(char *local_buffer){
729        char command[16];
730        double lat;
731        char sign;
732
733        lat=fabs(latitude);
734        if (latitude>0){
735                sign='+';
736        }
737        else {
738                sign='-';
739        }
740
741        sprintf(command,"I%c%.2d%.2d%.1d", sign,
742                        (int)lat,
743                        (int)(lat*(double)60)%60,
744                        ((int)(lat*(double)600))%10);
745
746        if (portWrite(command) < 0)
747                return -1;
748        return 0;
749}
750
751int get_TemmaLST(char *local_buffer){
752        if (portWrite("g") < 0)
753                return -1;
754
755        portRead(local_buffer,-1,TEMMA_TIMEOUT);
756        if(local_buffer[0]=='g'){
757                return 0;
758        }
759        else 
760                return -1;
761}
762
763
764int set_TemmaLST(char *local_buffer){
765        char command[16];
766        snprintf(command,7,"T%s",local_buffer);
767
768        if (portWrite(command) < 0)
769                return -1;
770        return 0;
771}
772
773
774int get_TemmaCometTracking(char *local_buffer){
775        if (portWrite("lm") < 0)
776                return -1;
777        portRead(local_buffer,-1,TEMMA_TIMEOUT);
778        if(strstr(local_buffer, "lm")==local_buffer){
779                return 0;
780        }
781        else 
782                return -1;
783}
784
785int set_TemmaStandbyState(int on){
786        if (on){
787                return portWrite("STN-ON");
788        }
789        else{
790                return portWrite("STN-OFF");
791        }
792        return 0;
793}
794
795int get_TemmaStandbyState(unsigned char *local_buffer){
796        int nb;
797        int status;
798
799        if ((nb=portWrite("STN-COD")) < 0){
800                IDSetSwitch (&RAmotorSw, "I/O error when asking RAmotor status");
801                return -1;
802        }
803
804        if((status=portRead(local_buffer,-1,TEMMA_TIMEOUT)==SUCCESS)){
805                if( ( (unsigned char *) strstr(local_buffer, "stn"))==local_buffer){
806                        local_buffer[7]=0;
807                        if (strstr(local_buffer,"on")){ /* stanby on */
808                                RAmotorSw.s = IPS_OK;
809                                RAmotor[0].s = ISS_OFF;
810                                RAmotor[1].s = ISS_ON;
811                                IDSetSwitch (&RAmotorSw, "RA motor is off.");
812                        }
813                        else{
814                                if (strstr(local_buffer,"off")){ /* stanby off */ 
815                                        RAmotorSw.s = IPS_OK;
816                                        RAmotor[0].s = ISS_ON;
817                                        RAmotor[1].s = ISS_OFF;
818                                        IDSetSwitch (&RAmotorSw, "RA motor is on.");
819                                }
820                                else {
821                                        RAmotorSw.s = IPS_OK;
822                                        IDSetSwitch (&RAmotorSw, "I/O error when getting RAmotor status");
823                                }
824                        }
825                }
826                return 0;
827        }
828        if (status<=ETIMEOUT && status >=ECOMMAND){
829                IDSetSwitch(&RAmotorSw, "%s", errormes[ETIMEOUT - status]);
830        }
831       
832        return -1;
833}
834
835int set_TemmaCometTracking(char *local_buffer){
836        char command[16];
837
838        snprintf(command,15,"LM%s",local_buffer);
839        if (portWrite(command) < 0)
840                return -1;
841        return 0;
842}
843
844int set_TemmaSolarRate(void){
845        if (portWrite("LK") < 0)
846                return -1;
847        return 0;
848}
849
850int set_TemmaStellarRate(void){
851        if (portWrite("LL") < 0)
852                return -1;
853        return 0;
854}
855
856
857int switch_Temmamountside(void){
858        if (portWrite("PT") < 0)
859                return -1;
860        return 0;
861}
862
863/**********************************************************************
864 * Comm
865 **********************************************************************/
866
867int openPort(const char *portID) {
868        struct termios ttyOptions;
869
870        if ( (fd = open(portID, O_RDWR)) == -1)
871                return -1;
872        memset(&ttyOptions, 0, sizeof(ttyOptions));
873        tcgetattr(fd, &ttyOptions);
874
875        /* 8 bit, enable read */
876        ttyOptions.c_cflag |= CS8;
877        /* parity */
878        ttyOptions.c_cflag |= PARENB;
879        ttyOptions.c_cflag &= ~PARODD;
880        ttyOptions.c_cflag &= ~CSTOPB;
881        ttyOptions.c_cflag |= CRTSCTS;
882
883        /* set baud rate */
884        cfsetispeed(&ttyOptions, B19200);
885        cfsetospeed(&ttyOptions, B19200);
886
887        /* set input/output flags */
888        ttyOptions.c_iflag = IGNBRK;
889
890        /* Read at least one byte */
891        ttyOptions.c_cc[VMIN] = 1;
892        ttyOptions.c_cc[VTIME] = 5;
893
894        /* Misc. */
895        ttyOptions.c_lflag = 0;
896        ttyOptions.c_oflag = 0;
897
898        /* set attributes */
899        tcsetattr(fd, TCSANOW, &ttyOptions);
900
901        /* flush the channel */
902        tcflush(fd, TCIOFLUSH);
903        return (fd);
904}
905
906int portWrite(char * buf) {
907  int nbytes=strlen(buf); /*, totalBytesWritten;*/
908        int bytesWritten = 0; 
909        /*int retry=10;*/
910
911        bytesWritten = write(fd, buf, nbytes);
912        bytesWritten += write(fd, "\r\n", 2);
913        /*fprintf(stderr,"portwrite :%d octets %s\n", bytesWritten, buf);*/
914
915        if (bytesWritten!=nbytes+2){
916                perror("write error: ");
917                IDLog("Error writing to port");
918                return EWRITE;
919        }
920        return (bytesWritten);
921}
922
923int portRead(char *buf, int nbytes, int timeout) {
924        /*
925           A very basic finite state machine monitors
926           the bytes read ;
927           state 0 : read regular bytes
928           state 1 : just read a \n, waiting for a \r
929           state 2 : read a \n and a \r, command is over.
930
931           Not sure it is useful here but I use a more
932           sophisticated version of this with a GPS receiver
933           and it is robust and reliable
934
935           We return a null terminated string.
936         */
937
938  int bytesRead = 0, state=0, /*i=0,*/ current=0;
939  /*int totalBytesRead = 0;*/
940        int err;
941
942        if ( (err = TemmareadOut(timeout)) ){
943                switch (err){
944                        case ETIMEOUT:
945                                IDLog("Error: timeout while reading");
946                                return err;
947                }
948        }
949
950        while (read(fd,buf+bytesRead,1)==1){
951                /*              fprintf(stderr,"%c",buf[bytesRead]); */
952                fflush(NULL);
953                switch (state) {
954                        case 0:
955                                if(buf[bytesRead]==13)
956                                        state=1;
957                                break;
958
959                        case 1:
960                                if(buf[bytesRead]==10)
961                                        state=2;
962                                else
963                                        if(buf[bytesRead]==13)
964                                                state=1;
965                                        else
966                                                state=0;
967                                break;
968                }
969
970                ++current;
971
972                if (state==2){
973                        /*process(buf);*/
974                        buf[bytesRead+1]=0;
975                        state=current=0;
976                        return SUCCESS;
977                }
978
979                bytesRead=current;
980        }
981        return state;
982}
983
984int TemmareadOut(int timeout) {
985        struct timeval tv;
986        fd_set readout;
987        int retval;
988
989        FD_ZERO(&readout);
990        FD_SET(fd, &readout);
991
992        /* wait for 'timeout' seconds */
993        tv.tv_sec = timeout;
994        tv.tv_usec = 0;
995
996        /* Wait till we have a change in the fd status */
997        retval = select (fd+1, &readout, NULL, NULL, &tv);
998
999        /* Return 0 on successful fd change */
1000        if (retval > 0)
1001                return 0;
1002        /* Return -1 due to an error */
1003        else if (retval == EREAD)
1004                return retval;
1005        /* Return -2 if time expires before anything interesting happens */
1006        else {
1007                return ETIMEOUT;
1008        }
1009}
1010
Note: See TracBrowser for help on using the repository browser.