source: BAORadio/libindi/v1/drivers/telescope/temmadriver.c@ 689

Last change on this file since 689 was 490, checked in by campagne, 15 years ago

import libindi (JEC)

File size: 21.1 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(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.