source: BAORadio/libindi/v1/drivers/video/stvdriver.c@ 689

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

import libindi (JEC)

File size: 42.0 KB
Line 
1#if 0
2 STV Low Level Driver
3 Copyright (C) 2006 Markus Wildi, markus.wildi@datacomm.ch
4 The initial work is based on the program STVremote by Shashikiran Ganesh.
5 email: gshashikiran_AT_linuxmail_dot_org
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#include <unistd.h>
23#include <string.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <errno.h>
27#include <stdio.h>
28#include <time.h>
29#include <stdlib.h>
30
31#include "stvdriver.h"
32
33/* Config parameters */
34#include <config.h>
35
36#ifdef HAVE_NOVA_H
37#include <libnova.h>
38#endif
39
40#ifndef _WIN32
41#include <termios.h>
42#endif
43
44/* INDI Common Routines/RS232 */
45
46#include "indicom.h"
47
48extern int fd ;
49extern char tracking_buf[] ;
50struct termios orig_tty_setting; /* old serial port setting to restore on close */
51struct termios tty_setting; /* new serial port setting */
52
53
54#define FALSE 0
55#define TRUE 1
56
57/*int tty_read( int fd, char *buf, int nbytes, int timeout, int *nbytes_read) ; */
58/*int tty_write( int fd, const char *buffer, int *nbytes_written) ; */
59void ISUpdateDisplay( int buffer, int line) ;
60
61int STV_portWrite( char *buf, int nbytes) ;
62int STV_TXDisplay( void) ;
63int STV_TerminateTXDisplay( void) ;
64int STV_FileStatus( int) ;
65int STV_DownloadComplete( void) ;
66int STV_RequestImage( int compression, int buffer, int x_offset, int y_offset, int *length, int *lines, int image[][320], IMAGE_INFO *image_info) ;
67int STV_RequestImageData( int compression, int *data, int j, int length, int *values) ;
68int STV_Download( void) ;
69int STV_DownloadAll( void) ;
70int STV_RequestAck( void) ;
71int STV_CheckHeaderSum( unsigned char *buf) ;
72int STV_CheckDataSum( unsigned char *data) ;
73int STV_PrintBuffer( unsigned char *buf, int n ) ;
74int STV_PrintBufferAsText( unsigned char *buf, int n ) ;
75int STV_CheckAck( unsigned char *buf) ;
76int STV_SendPacket( int cmd, int *data, int n) ;
77int STV_ReceivePacket( unsigned char *buf, int mode) ;
78int STV_DecompressData( unsigned char *data, int *values, int length, int expected_n_values) ;
79int STV_BufferStatus( int buffer) ;
80void STV_PrintBits( unsigned int x, int n) ;
81
82unsigned int STV_RecombineInt( unsigned char low_byte, unsigned char high_byte) ;
83unsigned int STV_GetBits( unsigned int x, int p, int n) ;
84
85int STV_MenueSetup( int delay) ;
86int STV_MenueDateTime( int delay) ;
87int STV_MenueCCDTemperature( int delay) ;
88
89typedef struct {
90
91 double ccd_temperature ;
92
93} DISPLAY_INFO ;
94
95DISPLAY_INFO di ;
96
97
98/* STV Buttons */
99
100int STV_LRRotaryDecrease(void) {
101 int data[]={LR_ROTARY_DECREASE_PATTERN} ;
102 return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ;
103}
104
105int STV_LRRotaryIncrease(void) {
106 int data[]={ LR_ROTARY_INCREASE_PATTERN} ;
107 return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ;
108}
109
110int STV_UDRotaryDecrease(void) {
111 int data[]={UD_ROTARY_DECREASE_PATTERN} ;
112 return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ;
113}
114
115int STV_UDRotaryIncrease(void) {
116 int data[]={UD_ROTARY_INCREASE_PATTERN} ;
117 return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ;
118}
119
120int STV_AKey(void) { /* Parameter button */
121 int data[]={A_KEY_PATTERN} ;
122 return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ;
123}
124
125int STV_BKey(void) { /* Value Button */
126 int data[]={ B_KEY_PATTERN} ;
127 return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ;
128}
129
130int STV_Setup(void) {
131 int data[]={SETUP_KEY_PATTERN} ;
132 return STV_SendPacket(SEND_KEY_PATTERN, data, 1);
133}
134
135int STV_Interrupt(void) {
136 int data[]={INT_KEY_PATTERN} ;
137 return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ;
138}
139
140int STV_Focus(void) {
141 int data[]= {FOCUS_KEY_PATTERN} ;
142 return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ;
143}
144
145int STV_Image(void) {
146 int data[]={IMAGE_KEY_PATTERN} ;
147 return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ;
148}
149
150int STV_Monitor(void) {
151 int data[]={MONITOR_KEY_PATTERN} ;
152 return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ;
153}
154
155int STV_Calibrate(void) {
156 int data[]={CAL_KEY_PATTERN} ;
157 return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ;
158}
159
160int STV_Track(void) {
161 int data[]={TRACK_KEY_PATTERN} ;
162 return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ;
163}
164
165int STV_Display(void) {
166 int data[]={DISPLAY_KEY_PATTERN} ;
167 return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ;
168}
169
170int STV_FileOps(void) {
171 int data[]={FILEOPS_KEY_PATTERN} ;
172 return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ;
173}
174
175int STV_RequestImageInfo(int buffer, IMAGE_INFO *image_info) {
176
177 int i ;
178 int length ;
179 int res ;
180 int data[]= {buffer} ;
181 unsigned char buf[1024] ;
182 unsigned int value[21] ;
183
184 if(( res= STV_BufferStatus( buffer)) != 0) {
185
186 if( res== 1) {
187 /*fprintf( stderr," STV_RequestImageInfo buffer empty %d\n", buffer) ; */
188 return res ; /* Buffer is empty */
189 } else {
190 fprintf( stderr," STV_RequestImageInfo error %d\n", res) ;
191 return res ;
192 }
193 }
194
195 res= STV_SendPacket( REQUEST_IMAGE_INFO, data, 1) ;
196 usleep(50000) ;
197 res= STV_ReceivePacket( buf, 0) ;
198
199 if(buf[1] != REQUEST_IMAGE_INFO) {
200
201 /*length= buf[3] * 0x100 + buf[2] ; */
202 /*res= STV_PrintBuffer(buf, 6+ length+ 2) ; */
203
204AGAINI: if(( res= STV_ReceivePacket( buf, 0)) < 0) { /* STV answers with a packet 0x03 sometimes, should be 0x04 */
205 return -1 ;;
206 }
207 if(buf[1] != REQUEST_IMAGE_INFO) { /* Second try */
208 fprintf( stderr, "STV_RequestImageInfo: expected REQUEST_IMAGE_INFO, received %d, try again\n", buf[1]) ;
209 goto AGAINI ;
210 }
211 }
212
213 length= buf[3] * 0x100 + buf[2];
214
215 /* DECODE it */
216
217 for( i= 6; i < length; i+= 2) {
218 value[( i- 6)/2]= STV_RecombineInt( buf[ i], buf[ i+1]) ;
219 }
220
221 image_info->descriptor = value[0] ;
222
223
224 /* Decode the descriptor */
225
226 /*STV_PrintBits(( unsigned int)value[0], 16) ; */
227
228 if(( image_info->descriptor & ID_BITS_MASK)== ID_BITS_10) {
229
230 /* fprintf( stderr, "ADC Resolution: 10 bits\n") ; */
231
232 } else if(( image_info->descriptor & ID_BITS_MASK )== ID_BITS_8) {
233
234 /*fprintf( stderr, "Resolution: 8 bits (focus mode only)\n") ; */
235 }
236
237 if(( image_info->descriptor & ID_UNITS_MASK)== ID_UNITS_INCHES) {
238
239 /*fprintf( stderr, "Units: inch\n") ; */
240
241 } else if(( image_info->descriptor & ID_UNITS_MASK)== ID_UNITS_CM) {
242
243 /*fprintf( stderr, "Unis: cm\n") ; */
244 }
245
246 if(( image_info->descriptor & ID_SCOPE_MASK)== ID_SCOPE_REFRACTOR) {
247
248 /*fprintf( stderr, "Refractor\n") ; */
249 } else if(( image_info->descriptor & ID_SCOPE_MASK)== ID_SCOPE_REFLECTOR) {
250
251 /*fprintf( stderr, "Reflector\n") ; */
252 }
253
254
255 if(( image_info->descriptor & ID_DATETIME_MASK)== ID_DATETIME_VALID) {
256
257 /*fprintf( stderr, "Date and time valid\n") ; */
258 } else if(( image_info->descriptor & ID_DATETIME_MASK)== ID_DATETIME_INVALID) {
259
260 /*fprintf( stderr, "Date and time invalid\n") ; */
261 }
262
263
264 if(( image_info->descriptor & ID_BIN_MASK)== ID_BIN_1X1) {
265
266 image_info->binning=1 ;
267 } else if(( image_info->descriptor & ID_BIN_MASK)== ID_BIN_2X2) {
268
269 image_info->binning=2 ;
270 } else if(( image_info->descriptor & ID_BIN_MASK)== ID_BIN_3X3) {
271
272 image_info->binning=3 ;
273 }
274
275 if(( image_info->descriptor & ID_PM_MASK)== ID_PM_PM) {
276
277 /*fprintf( stderr, "Time: PM\n") ; */
278 } else if(( image_info->descriptor & ID_PM_MASK)== ID_PM_AM) {
279
280 /*fprintf( stderr, "Time: AM\n") ; */
281 }
282
283 /* ToDo: Include that to the fits header */
284 if(( image_info->descriptor & ID_FILTER_MASK)== ID_FILTER_LUNAR) {
285 /*fprintf( stderr, "Filter: Lunar\n") ; */
286 } else if(( image_info->descriptor & ID_FILTER_MASK)== ID_FILTER_NP ) {
287 /*fprintf( stderr, "Filter: clear\n") ; */
288 }
289
290 /* ToDo: Include that to the fits header */
291 if(( image_info->descriptor & ID_DARKSUB_MASK )== ID_DARKSUB_YES) {
292
293 /*fprintf( stderr, "Drak sub yes\n") ; */
294 } else if(( image_info->descriptor & ID_DARKSUB_MASK )== ID_DARKSUB_NO) {
295
296 /*fprintf( stderr, "Dark sub no\n") ; */
297 }
298
299 if(( image_info->descriptor & ID_MOSAIC_MASK)== ID_MOSAIC_NONE) {
300
301 /*fprintf( stderr, "Is NOT a mosaic\n") ; */
302 } else if(( image_info->descriptor & ID_MOSAIC_MASK)== ID_MOSAIC_SMALL) {
303
304 /*fprintf( stderr, "Is a small mosaic\n") ; */
305 } else if(( image_info->descriptor & ID_MOSAIC_MASK)== ID_MOSAIC_LARGE) {
306
307 /*fprintf( stderr, "Is a large mosaic\n") ; */
308 }
309
310 image_info->height = value[1] ;
311 image_info->width = value[2] ;
312 image_info->top = value[3] ;
313 image_info->left = value[4] ;
314
315 /* Exposure time */
316
317 if((value[5]>= 100 ) && (value[5]<= 60000)) {
318
319 image_info->exposure = ((float)value[5]) * 0.01;
320
321 } else if((value[5]>= 60001 ) && (value[5]<= 60999)){
322
323 image_info->exposure = (( float)value[5]- 60000.) *.001 ;
324 } else {
325 fprintf( stderr, "Error Exposure time %d\n", value[5]) ;
326 image_info->exposure = -1. ;
327 }
328
329 image_info->noExposure = value[6] ;
330 image_info->analogGain = value[7] ;
331 image_info->digitalGain= value[8] ;
332 image_info->focalLength= value[9] ;
333 image_info->aperture = value[10] ;
334
335
336 image_info->packedDate = value[11] ;
337 image_info->year = STV_GetBits( value[11], 6, 7) + 1999;
338 image_info->day = STV_GetBits( value[11], 11, 5) ;
339 image_info->month = STV_GetBits( value[11], 15, 4) ;
340
341 image_info->packedTime = value[12];
342 image_info->seconds = STV_GetBits( value[12], 5, 6) ;
343 image_info->minutes = STV_GetBits( value[12], 11, 6) ;
344 image_info->hours = STV_GetBits( value[12], 15, 4) ;
345
346 if(( image_info->descriptor & ID_PM_PM) > 0) {
347
348 image_info->hours += 12 ;
349 }
350
351 if((value[13] & 0x8000)== 0x8000) {
352
353 image_info->ccdTemp= (float)(0xffff - value[13]) /100. ;
354
355 } else {
356
357 image_info->ccdTemp= (float)value[13]/100. ;
358 }
359
360 image_info->siteID = value[14] ;
361 image_info->eGain = value[15] ;
362 image_info->background = value[16] ;
363 image_info->range = value[17] ;
364 image_info->pedestal = value[18] ;
365 image_info->ccdTop = value[19] ;
366 image_info->ccdLeft = value[20] ;
367
368
369/* fprintf( stderr, "descriptor:%d 0x%2x 0x%2x\n", image_info->descriptor, buf[6], buf[6+1]) ; */
370/* fprintf( stderr, "height:%d\n", image_info->height) ; */
371/* fprintf( stderr, "width:%d\n", image_info->width) ; */
372/* fprintf( stderr, "top:%d\n", image_info->top) ; */
373/* fprintf( stderr, "left:%d\n", image_info->left) ; */
374/* fprintf( stderr, "exposure:%f\n", image_info->exposure) ; */
375/* fprintf( stderr, "noExposure:%d\n", image_info->noExposure) ; */
376/* fprintf( stderr, "analogGain:%d\n", image_info->analogGain) ; */
377/* fprintf( stderr, "digitalGain:%d\n", image_info->digitalGain) ; */
378/* fprintf( stderr, "focalLength:%d\n", image_info->focalLength) ; */
379/* fprintf( stderr, "aperture:%d\n", image_info->aperture) ; */
380/* fprintf( stderr, "packedDate:%d\n", image_info->packedDate) ; */
381/* fprintf( stderr, "Year:%d\n", image_info->year) ; */
382/* fprintf( stderr, "Day:%d\n", image_info->day) ; */
383/* fprintf( stderr, "Month:%d\n", image_info->month) ; */
384/* fprintf( stderr, "packedTime:%d\n", image_info->packedTime) ; */
385/* fprintf( stderr, "Seconds:%d\n", image_info->seconds) ; */
386/* fprintf( stderr, "minutes:%d\n", image_info->minutes) ; */
387/* fprintf( stderr, "hours:%d\n", image_info->hours) ; */
388/* fprintf( stderr, "ccdTemp:%f\n", image_info->ccdTemp) ; */
389/* fprintf( stderr, "siteID:%d\n", image_info->siteID) ; */
390/* fprintf( stderr, "eGain:%d\n", image_info->eGain) ; */
391/* fprintf( stderr, "background:%d\n", image_info->background) ; */
392/* fprintf( stderr, "range :%d\n", image_info->range ) ; */
393/* fprintf( stderr, "pedestal:%d\n", image_info->pedestal) ; */
394/* fprintf( stderr, "ccdTop :%d\n", image_info->ccdTop) ; */
395/* fprintf( stderr, "ccdLeft:%d\n", image_info->ccdLeft) ; */
396
397 return 0 ;
398}
399
400int STV_RequestImage( int compression, int buffer, int x_offset, int y_offset, int *length, int *lines, int image[][320], IMAGE_INFO *image_info) {
401
402 int i, j ;
403 int res ;
404 int n_values ;
405 unsigned char buf[0xffff] ;
406 int values[1024] ;
407 int data[]= { 0, y_offset, *length, buffer} ; /* Offset row, Offset line, length, buffer number */
408 int XOFF ;
409
410 /* fprintf(stderr, "STV_RequestImage: --------------------------------buffer= %d, %d\n", buffer, lines) ; */
411
412 if(( res= STV_RequestImageInfo( buffer, image_info)) != 0) { /* Trigger for download */
413 /* buffer empty */
414 return res ;
415 }
416 res= STV_BKey() ; /* "press" the STV Value button */
417 usleep(50000) ;
418 res= STV_ReceivePacket(buf, 0) ;
419
420 /* Check the boundaries obtained from the image data versus windowing */
421 /* Take the smaller boundaries in each direction */
422
423 if( x_offset > image_info->height) {
424 x_offset= image_info->height ;
425 }
426 XOFF= image_info->top + x_offset ;
427
428 if( y_offset > image_info->width) {
429 y_offset= image_info->width ;
430 }
431 data[1]= image_info->left + y_offset ;
432
433 if( *length > image_info->width- y_offset) {
434 *length= image_info->width- y_offset ;
435 }
436 data[2]= *length ;
437
438 if( *lines > image_info->height- x_offset) {
439 *lines= image_info->height- x_offset ;
440 }
441
442 /*fprintf(stderr, "STV_RequestImage: DATA 0=%d, 1=%d, 2=%d, 3=%d, length=%d, lines=%d\n", data[0], data[1], data[2], data[3], *length, *lines) ; */
443
444 for( j= 0 ; j < *lines ; j++) {
445
446 data[0]= j + XOFF; /*line */
447
448 if(( n_values= STV_RequestImageData( compression, data, j, *length, values)) < 0) {
449 fprintf(stderr, "STV_RequestImage: Calling STV_RequestImageData failed %d\n", n_values) ;
450 return n_values ;
451 } else {
452 for( i= 0; i < n_values ; i++) {
453
454 image[j][i]= values[i] ;
455 }
456 ISUpdateDisplay( buffer, j) ;
457 }
458 }
459 /* Read the 201th line, see mosaic mode */
460
461 /* ToDo: analyze/display the data or use them in the fits header(s) */
462 data[0]= 200; /*line */
463
464 if(( res= STV_RequestImageData( 1, data, 200, *length, values)) < 0) {
465
466 return res ;
467 } else {
468 for( i= 0 ; i< n_values ; i++) {
469
470 /* fprintf( stderr, "%d: %d ", i, values[i]) ; */
471 }
472 /* fprintf( stderr, "\n") ; */
473 }
474 res= STV_DownloadComplete() ;
475 ISUpdateDisplay( buffer, -j) ;
476 return 0 ;
477}
478
479int STV_RequestImageData( int compression, int *data, int j, int length, int *values) {
480
481 int i ;
482 int res ;
483 int data_length ;
484 int n_values ;
485 unsigned char buf[0xffff] ;
486
487 data_length= -1 ;
488
489 if( compression== ON) { /* compressed download */
490
491 if(( res= STV_SendPacket( REQUEST_COMPRESSED_IMAGE_DATA, data, 4)) != 0){
492
493 fprintf(stderr, "STV_RequestImageData: could not write\n") ;
494 return -1 ;
495 }
496
497AGAINC: if(( res= STV_ReceivePacket(buf, 0)) > 0) {
498
499
500 if( buf[1] != REQUEST_COMPRESSED_IMAGE_DATA) {
501
502 if( buf[1] != DISPLAY_ECHO) {
503 if( buf[1] != ACK) {
504 fprintf(stderr, "STV_RequestImageData: expected REQUEST_COMPRESSED_IMAGE_DATA, received %2x\n", buf[1]) ;
505 }
506 }
507 goto AGAINC ;
508 }
509
510 data_length= (int)buf[3] * 0x100 + (int)buf[2] ;
511
512 if(( n_values= STV_DecompressData((buf+6), values, data_length, length)) < 0 ) {
513
514 n_values= -n_values ;
515 fprintf( stderr, "SEVERE ERROR on Line %d, pixel position=%d\n", j, n_values) ;
516 _exit( -1) ;
517 }
518
519 if( n_values == length) {
520
521 return n_values ;
522 } else {
523
524 fprintf( stderr, "SEVERE Error: Length not equal, Line: %d, %d != %d, data %2x %2x, values %d, %d\n", j, n_values, length, buf[ 6+ length -2], buf[ 6+ length -1], values[n_values-2], values[n_values-1]) ;
525 _exit( 1) ;
526 }
527 } else {
528 fprintf( stderr, "Error: waiting for data on the serial port at line %d\n", j) ;
529 return -1 ;
530 }
531 } else { /* uncompressed download */
532
533 if(( res= STV_SendPacket( REQUEST_IMAGE_DATA, data, 4))== 0) {
534
535AGAINU: if(( res= STV_ReceivePacket(buf, 0)) > 0) {
536
537 if( buf[1] != REQUEST_IMAGE_DATA) {
538 if( buf[1] != DISPLAY_ECHO) {
539 if( buf[1] != ACK) {
540 fprintf(stderr, "STV_RequestImageData: expected REQUEST_IMAGE_DATA, received %2x\n", buf[1]) ;
541 }
542 }
543 goto AGAINU ;
544 }
545
546 data_length= (int)buf[3] * 0x100 + (int)buf[2] ;
547
548 for( i= 0; i < data_length ; i += 2) {
549
550 values[i/2]= STV_RecombineInt(buf[6 + i], buf[7 + i]) ;
551 }
552 return data_length/2 ;
553 /*ISUpdateDisplay( buffer, j) ; */ /* Update the display of the INDI client */
554 } else {
555 fprintf( stderr, "Error: waiting for data on the serial port at line %d\n", j) ;
556 return -1 ;
557 }
558 } else {
559 fprintf( stderr, "STV_RequestImageData: error writing %d\n", res) ;
560 }
561 }
562 return 0 ;
563}
564int STV_DecompressData( unsigned char *data, int *values, int length, int expected_n_values) {
565
566 int i, n_values ;
567 int value ;
568 int base ;
569
570 base= STV_RecombineInt( data[0], data[1]) ; /*STV Manual says: MSB then LSB! */
571
572 values[0]= base ;
573 i= 2 ;
574 n_values= 1 ;
575
576 while( i < length ) {
577
578 if( (( data[ i] & 0xc0))== 0x80) { /*two bytes, first byte: bit 7 set, 6 cleared, 14 bits data */
579
580 if(( data[ i] & 0x20)== 0x20) { /* minus sign set? */
581
582 value= - ((int)(( (~data[ i] & 0x1f)) * 0x100) + (((int) (~data[ i+ 1])) & 0xff))- 1 ; /* value without sign */
583 } else {
584
585 value= (int) (( data[ i] & 0x1f) * 0x100) + (int) (data[ i + 1]) ;
586 }
587
588 base= value + base ; /* new base value */
589 values[n_values++]= base ; /*pixel data */
590 i += 2 ;
591
592 } else if((( data[ i] & 0x80))== 0) { /* one byte: bit 7 clear (7 bits data) */
593
594 if(( data[ i] & 0x40)== 0x40) { /* minus sign set? */
595
596 value= - (int) ( (~(data[ i])) & 0x3f) - 1 ; /* value without sign */
597 } else {
598
599 value= (int) ( data[ i] & 0x3f) ;
600 /*fprintf( stderr, "Value 7P: %d, pixel value: %d, length %d, pix=%d\n", value, value+ base, length, n_values) ; */
601 }
602 /* Sometimes the STV send a 0 at the end, thats not very likely a pixel to pixel variation */
603 /* I checked the last decompressed pixel value against the last uncompressed pixel value */
604 /* with different images - it seems to be ok. */
605 if(( value == 0) &&( n_values== expected_n_values)){
606 /*fprintf( stderr, "Ignoring byte %d, Zero difference obtained values: %d\n", i, n_values) ; */
607 } else {
608 base= value + base ;
609 values[n_values++]= base ;
610 }
611 i++ ;
612 } else if( (( data[ i] & 0xc0))== 0xc0) { /*two bytes, values= pixel_n/4 */
613
614
615 /*STV_PrintBits( data[ i], 8) ; */
616 /*STV_PrintBits( data[ i+ 1], 8) ; */
617
618
619 value= 4* ((int) (( data[ i] & 0x3f) * 0x100) + (int) (data[ i + 1])) ;
620 /*fprintf( stderr, "Value 14P: %d, pixel value: %d, length %d, pix=%d\n", value, value+ base, length, n_values) ; */
621
622 base= value ;
623 values[n_values++]= value ;
624
625 i += 2 ;
626 /*return -n_values ; */
627 } else {
628
629 fprintf( stderr, "Unknown compression case: %2x, length %d, i=%d\n", data[ i], length, i) ;
630 return -n_values ; /* exit */
631 }
632 }
633 return n_values ;
634}
635
636int STV_TXDisplay(void) {
637
638 int data[]={TRUE} ;
639 return STV_SendPacket( DISPLAY_ECHO, data, 1);
640}
641
642int STV_TerminateTXDisplay(void) {
643 int res ;
644 int data[]={FALSE} ;
645
646 res= STV_SendPacket( DISPLAY_ECHO, data, 1);
647
648 /* Despite the manual says so, I not always see an ACK packet */
649 /* So i flush it for the moment */
650
651 tcflush(fd, TCIOFLUSH);
652 return res ;
653}
654
655int STV_FileStatus(int status) {
656
657 int data[]= {status} ;
658 return STV_SendPacket( FILE_STATUS, data, 1);
659}
660
661int STV_DownloadComplete(void) {
662
663 return STV_SendPacket( DOWNLOAD_COMPLETE, NULL, 0);
664}
665
666int STV_Download(void) {
667
668 return STV_SendPacket( REQUEST_DOWNLOAD, NULL, 0) ;
669}
670
671int STV_DownloadAll(void) {
672
673 return STV_SendPacket( REQUEST_DOWNLOAD_ALL, NULL, 0);
674}
675
676int STV_RequestAck(void) {
677 int data[]={0x06,0x06,0x06 } ;
678 /* SBIG manual says contains data, which? */
679 return STV_SendPacket( REQUEST_ACK, data, 3) ;
680}
681
682int STV_BufferStatus( int buffer){
683
684 unsigned char buf[1024];
685 int buffers ;
686 int res ;
687 int val ;
688
689 /*fprintf(stderr, "STV_BufferStatus entering\n") ; */
690 usleep(50000) ;
691 if(( res= STV_SendPacket( REQUEST_BUFFER_STATUS, NULL, 0)) < 0) {
692 fprintf( stderr, "STV_BufferStatus: Error requesting buffer status: %d\n", buffer) ;
693 return -1 ;
694 } else {
695 /*fprintf( stderr, "STV_BufferStatus %2d\n", buffer) ; */
696 }
697
698AGAIN: if(( res= STV_ReceivePacket( buf, 0)) < 0) {
699 fprintf( stderr, "STV_BufferStatus: Error reading: %d\n", res) ;
700 return -1 ;;
701 }
702
703 if( buf[1]== REQUEST_BUFFER_STATUS) {
704
705 buffers= STV_RecombineInt( buf[6], buf[7]) * 0x10000 + STV_RecombineInt( buf[8], buf[9]) ;
706
707 if(( val= STV_GetBits( buffers, buffer, 1))== 1) {
708
709 res= 0 ; /* image present */
710 } else {
711
712 /*fprintf( stderr, "STV_BufferStatus %2d is empty\n", buffer) ; */
713 res= 1 ; /* empty */
714 }
715 } else {
716 /* The SBIG manual does not specify an ACK, but it is there (at least sometimes) */
717 if(( val= STV_CheckAck( buf))== 0) {
718 /*fprintf( stderr, "STV_BufferStatus SAW ACK, reading again\n") ; */
719 goto AGAIN ;
720 }
721 /* The SBIG manual does not specify the cmd in the answer */
722 if( buf[1] != DISPLAY_ECHO) {
723 fprintf( stderr, "STV_BufferStatus: unexpected cmd byte received %d\n", buf[1]) ;
724 val= STV_RecombineInt(buf[2], buf[3]) ;
725 res= STV_PrintBuffer( buf, 6+ val + 2) ;
726 return -1 ;
727 } else {
728 /* a display packet is silently ignored, there are many of this kind */
729 fprintf( stderr, "STV_BufferStatus DISPLAY_ECHO received, try again\n") ;
730 return -1 ;
731 }
732 }
733 /* fprintf(stderr, "STV_BufferStatus leaving\n") ; */
734 return res;
735}
736/* Low level communication */
737/* STV_ReceivePacket n_bytes read */
738int STV_ReceivePacket( unsigned char *buf, int mode) {
739
740 int i,j,k ;
741 int n_bytes=0 ;
742 int length=0 ;
743 int res ;
744 int trb=0 ;
745 int pos=0 ;
746 char display1[25] ;
747 char display2[25] ;
748
749 j= 0 ;
750 tracking_buf[ 0]= 0 ;
751
752 /*fprintf( stderr,"R") ; */
753
754 while(pos < 6) {
755
756 /* Read the header first, calculate length of data */
757 /* At higher speeds the data arrives in smaller chunks, assembling the packet */
758 if(( trb= read( fd, (char *)(buf + pos), 1))== -1) {
759 fprintf(stderr, "Error, %s\n", strerror(errno)) ;
760 }
761
762 if(buf[0]== 0xa5) {
763
764 if( pos== 5) {
765
766 pos++ ;
767 break ;
768 } else {
769
770 pos+= trb ; /* could be zero */
771 }
772 } else {
773 /* In tracking mode the STV sends raw data (time, brightnes, centroid x,y). */
774 /* Under normal operation here appear pieces of a packet. This could happen */
775 /* on start up or if something goes wrong. */
776
777 tracking_buf[ j++]= buf[pos] ;
778 /*fprintf(stderr, "READ: %d, read %d, pos %d, 0x%2x< %c\n", j, trb, pos, buf[pos], buf[pos]) ; */
779 }
780 }
781
782
783 if( j> 0) {
784 /* Sometimes the packets are corrupt, e.g. at the very beginning */
785 /* Or it is tracking information */
786
787 tracking_buf[ j]= 0 ;
788
789 if( mode== ON) { /* Tracking mode */
790
791 fprintf(stderr, "%s\n", tracking_buf) ;
792 } else {
793
794 for( k= 0 ; k< j; k++) {
795 if(!( tracking_buf[ k] >29 && tracking_buf[ k] < 127)) {
796 tracking_buf[ k]= 0x20 ; /* simply */
797 }
798 }
799 fprintf(stderr, "Not a packet: length: %d >%s<\n", j, tracking_buf) ;
800 }
801 }
802
803 n_bytes= pos ;
804
805 if(( buf[0]== 0xa5) && ( pos== 6)) { /* Check the sanity of the header part */
806 if((res= STV_CheckHeaderSum( buf))== 0) {
807
808 length= (int)buf[3] * 0x100 + (int)buf[2]; ;
809
810 if( length >0) {
811
812 trb= 0 ;
813 while( pos < 6 + length + 2) { /* header, data, check sum */
814
815 /* At higher speeds the data arrives in smaller chunks, assembling the packet */
816
817 if(( trb= read(fd, (char *)(buf + pos), (6 + length + 2)- pos))== -1) {
818
819 fprintf(stderr, "STV_ReceivePacket: Error reading at serial port, %s\n", strerror( errno)) ;
820 return -1 ;
821 }
822 pos += trb ;
823 }
824 n_bytes += pos ;
825 /*fprintf(stderr, "STV_ReceivePacket: LEAVING LOOP length %d, to read %d, read %d, pos %d\n", length, (6 + length + 2)- pos, trb, pos) ; */
826 }
827 } else {
828
829 fprintf(stderr, "STV_ReceivePacket: Header check failed\n") ;
830 return -1 ;
831 }
832 } else if( pos >0) {
833
834 for(i= 0 ; i < 6 ; i++) {
835 if( buf[i]==0xa5){
836 fprintf(stderr, "STV_ReceivePacket: pos= %d, saw 0xa5 at %d\n", pos, i) ;
837 }
838 }
839 return -1 ;
840 } else {
841
842 fprintf(stderr, "STV_ReceivePacket: NO 0xa5 until pos= %d\n", pos) ;
843 return -1 ;
844 }
845
846 if( length > 0) { /* Check the sanity of the data */
847
848 if((res= STV_CheckDataSum( buf))== -1) {
849 return -1 ;
850 }
851 }
852 /* Analyse the display and retrieve the values */
853 if( buf[1]== DISPLAY_ECHO) {
854
855 for( i=0 ; i< 24; i++) {
856
857 display1[i]= buf[i+6] ;
858 if( display1[i]== 0 ){
859 display1[i]= 0x32 ;
860 }
861 display2[i]= buf[i+30] ;
862 if( display2[i]== 0 ){
863 display2[i]= 0x32 ;
864 }
865 }
866 display1[24]= 0 ;
867 display2[24]= 0 ;
868
869 /*fprintf(stderr, "STV_ReceivePacket: DISPLAY1 %s<\n", display1) ; */
870 /*fprintf(stderr, "STV_ReceivePacket: DISPLAY2 %s<\n", display2) ; */
871
872 /* CCD temperature */
873 if(( res= strncmp( "CCD Temp.", display2, 9)) ==0) {
874 float t ;
875 res= sscanf( display2, "CCD Temp. %f", &t) ;
876 di.ccd_temperature= (double) t;
877 /*fprintf(stderr, "STV_ReceivePacket: Read from DISPLAY2 %g<\n", di.ccd_temperature ) ; */
878 }/* further values can be stored here */
879 }
880 return n_bytes ;
881}
882
883
884int STV_CheckHeaderSum( unsigned char *buf) {
885
886 int sum = buf[0] + buf[1] + buf[2] + buf[3] ; /* Calculated header sum */
887 int sumbuf= STV_RecombineInt( buf[4],buf[5]) ; /* STV packet header sum */
888
889 if(buf[0] != 0xa5) {
890
891 fprintf(stderr, "STV_CheckHeaderSum: Wrong start byte, skipping\n") ;
892 return -1 ;
893 }
894
895 if( sum != sumbuf) {
896
897 fprintf(stderr, "STV_CheckHeaderSum: NOK: %d==%d\n", sum, sumbuf ) ;
898 return -1 ;
899 }
900 return 0 ;
901}
902
903int STV_CheckDataSum( unsigned char *buf) {
904 /* *buf points to the beginning of the packet */
905
906 int j, n ;
907 int sum= 0 ;
908 int sumbuf=0 ;
909
910 n= STV_RecombineInt( buf[2], buf[3]) ;
911
912 if( n== 0) {
913 fprintf(stderr, "STV_CheckDataSum: No data present\n") ;
914 return 0 ;
915 }
916 sumbuf= STV_RecombineInt( buf[6 + n], buf[6 + n +1]) ;
917
918 for( j=0; j < n ; j++) {
919
920 sum += (int)buf[6 + j] ;
921 }
922 sum= sum & 0xffff ;
923
924 if( sum != sumbuf) {
925
926 fprintf(stderr, "DATA SUM NOK: %d !=%d\n", sum, sumbuf) ;
927 return -1 ;
928 }
929 return 0 ;
930}
931
932int STV_PrintBuffer( unsigned char *buf, int n ) {
933 /* For debugging purposes only */
934 int i ;
935
936 fprintf(stderr, "\nHEADER: %d bytes ", n) ;
937 for(i=0; i < n; i++) {
938
939 if( i==6) {
940 fprintf(stderr, "\nDATA : ") ;
941 }
942 fprintf(stderr, "%d:0x%2x<>%c< >>", i, (unsigned char)buf[i], (unsigned char)buf[i]) ;
943 /*STV_PrintBits((unsigned int) buf[i], 8) ; */
944 }
945 fprintf(stderr, "\n") ;
946
947 return 0 ;
948}
949int STV_PrintBufferAsText( unsigned char *buf, int n ) {
950 /* For debugging purposes only */
951 int i ;
952
953 fprintf(stderr, "\nHEADER: %d bytes ", n) ;
954 for(i=0; i < n; i++) {
955
956 if( i==6) {
957 fprintf(stderr, "\nDATA : ") ;
958 }
959 fprintf(stderr, "%c", (unsigned char)buf[i]) ;
960 }
961 fprintf(stderr, "\n") ;
962
963 return 0 ;
964}
965/* Aggregates a STV command packet */
966
967int STV_SendPacket( int cmd, int *data, int n) {
968
969 char buf[1024];
970
971 int j,l ;
972 int res ;
973 int sum ; /* check sum */
974
975 /* Header section */
976 buf[0] = (unsigned char) 0xa5; /* start byte */
977 buf[1] = (unsigned char) cmd; /* command byte */
978 buf[2] = (unsigned char) 2 * n; /* data length N (low byte) */
979 buf[3] = (unsigned char) 0x00; /* data length N (high byte) */
980
981 sum = buf[0] + buf[1] + buf[2] + buf[3]; /* header checksum */
982 buf[4] = (unsigned char) sum % 0x100; /* header checksum low byte */
983 buf[5] = (unsigned char) (sum / 0x100); /* header checksum high byte */
984
985 /* DATA section */
986 l= 0 ;
987 if( n > 0) {
988
989 l= 2 ; /* Two bytes per value are sent to STV */
990 for( j=0; j < 2 * n ; j += 2) {
991 buf[6+ j] = (unsigned char) (data[j/2] % 0x100); /* data low byte */
992 buf[7+ j] = (unsigned char) (data[j/2] / 0x100); /* data high byte */
993 }
994
995 sum = 0 ;
996 for( j=0; j < 2 * n ; j++) {
997
998 if((int)buf[6+ j] < 0 ) {
999
1000 sum = sum + 0xff+ (int)buf[6+ j] + 1 ;
1001
1002 } else {
1003
1004 sum = sum + (int)buf[6+ j] ;
1005 }
1006 }
1007 buf[6 + 2 * n ] = (unsigned char) (sum % 0x10000) ; /* data checksum (low byte) */
1008 buf[7 + 2 * n ] = (unsigned char) (sum / 0x100) ; /* data checksum (high byte) */
1009 }
1010 if(( res= STV_CheckHeaderSum( (unsigned char *) buf)) != 0) { /* Check outgoing packet as well */
1011
1012 fprintf(stderr, "STV_SendPacket: corrupt header\n") ;
1013
1014 if(n > 0) {
1015 if(( res= STV_CheckDataSum( (unsigned char *) buf)) != 0) {
1016 fprintf(stderr, "STV_SendPacket: corrupt data\n") ;
1017 }
1018 }
1019 }
1020 return STV_portWrite( buf, 8 + l * n ) ;
1021}
1022
1023/* Returns 0 or -1 in case of an error */
1024
1025int STV_portWrite( char *buf, int nbytes){
1026
1027 int bytesWritten = 0;
1028
1029 /*fprintf( stderr,"w") ; */
1030 while (nbytes > 0) {
1031
1032 if((bytesWritten = write(fd, buf, nbytes)) == -1) {
1033 fprintf(stderr, "STV_portWrite: Error writing at serial port, %s\n", strerror( errno)) ;
1034 /* return -1 ; */
1035 }
1036
1037 if (bytesWritten < 0) {
1038
1039 fprintf( stderr, "STV_portWrite: Error writing\n") ;
1040 return -1;
1041 } else {
1042
1043 buf += bytesWritten;
1044 nbytes -= bytesWritten;
1045 }
1046 }
1047 return nbytes ;
1048}
1049
1050int STV_CheckAck( unsigned char *buf) {
1051 /* Watch out for an ACK, for debugging purposes only */
1052 int i ;
1053 unsigned char ackseq[]= {0xa5, 0x06, 0x00, 0x00, 0xab, 0x00} ;
1054
1055 for(i= 0; i < 6; i++ ) {
1056
1057 if( buf[i] != ackseq[i] ) {
1058 return -1 ;
1059 }
1060 }
1061 return 0 ;
1062}
1063
1064unsigned int STV_RecombineInt( unsigned char low_byte, unsigned char high_byte) {
1065
1066 return (unsigned int) high_byte * (unsigned int)0x100 + (unsigned int)low_byte ;
1067}
1068
1069unsigned int STV_GetBits( unsigned int x, int p, int n){ /* from the C book */
1070
1071 return ( x >> (p+ 1-n)) & ~(~0 << n) ;
1072}
1073
1074void STV_PrintBits( unsigned int x, int n) {
1075 /* debugging purposes only */
1076 int i ;
1077 int res ;
1078 fprintf( stderr, "STV_PrintBits:\n") ;
1079
1080 if( n> 8) {
1081
1082 fprintf( stderr, "54321098 76543210\n") ;
1083
1084 } else {
1085 fprintf( stderr, "76543210\n") ;
1086 }
1087
1088 for( i= n; i >0 ; i--) {
1089
1090 if(( i==8) && (n> 8)) {
1091 fprintf( stderr, " ") ;
1092 }
1093 if(( res=STV_GetBits( x, i-1, 1))==0) {
1094 fprintf( stderr, "0") ;
1095 } else {
1096 fprintf( stderr, "1") ;
1097 }
1098 }
1099 fprintf( stderr, "\n") ;
1100}
1101
1102double STV_SetCCDTemperature( double set_value) {
1103
1104 int i ;
1105 int res ;
1106 int delay= 40000 ;
1107 unsigned char buf[1024] ;
1108 /* 1st step */
1109 res= STV_Interrupt() ; /* Reset Display */
1110 tcflush(fd, TCIOFLUSH);
1111 usleep( 100000) ;
1112
1113 STV_MenueCCDTemperature( delay) ;
1114
1115 for( i=0 ; i< 100 ; i++) { /* Change to the highest temperature */
1116 res= STV_LRRotaryIncrease() ;
1117 tcflush(fd, TCIOFLUSH);
1118 usleep( delay) ;
1119 }
1120
1121 di.ccd_temperature= 25.2 ; /* The actual value is set in STV_ReceivePacket, needed to enter the while() loop */
1122 i= 0 ;
1123 while( set_value < di.ccd_temperature) {
1124
1125 /*fprintf( stderr, "STV_SetCCDTemperature %g %g\n", set_value, di.ccd_temperature) ; */
1126 res= STV_LRRotaryDecrease() ; /* Lower CCD temperature */
1127 /*fprintf(stderr, ":") ; */
1128 usleep( 10000) ;
1129 res= STV_TerminateTXDisplay();
1130 usleep( 10000) ;
1131 res= STV_TXDisplay(); /* That's the trick, STV sends at least one display */
1132 res= STV_ReceivePacket( buf, 0) ; /* discard it */
1133
1134 /*STV_PrintBufferAsText( buf, res) ; */
1135 if(( res != 62) || ( i++ > 100)) { /* why 56 + 6?, 6 + 48 + 6 */
1136 STV_PrintBuffer( buf, res) ;
1137 /*STV_PrintBufferAsText( buf, res) ; */
1138 return 0.0 ;
1139 }
1140 }
1141 res= STV_Interrupt() ;
1142
1143 return di.ccd_temperature ;
1144}
1145
1146int STV_MenueCCDTemperature( int delay) {
1147
1148 int res ;
1149
1150 res= STV_MenueSetup( delay) ;
1151 usleep( delay) ;
1152 res= STV_UDRotaryIncrease() ; /* Change to CCD Temperature */
1153 /*usleep( delay) ; */
1154 tcflush(fd, TCIOFLUSH);
1155 return 0 ;
1156}
1157
1158#ifdef HAVE_NOVA_H
1159int STV_SetDateTime( char *times)
1160{
1161 int i ;
1162 int res ;
1163 int turn ;
1164 struct ln_date utm;
1165 int delay= 20000 ;
1166 /*fprintf(stderr, "STV_SetTime\n") ; */
1167
1168 if((times== NULL) || (( res= strlen(times))==0))
1169 ln_get_date_from_sys(&utm);
1170 else
1171 {
1172 if( extractISOTime( times, &utm) < 0)
1173 {
1174 fprintf( stderr, "Bad time string %s\n", times) ;
1175 return -1 ;
1176 }
1177 }
1178 /* Print out the date and time in the standard format. */
1179 /*fprintf( stderr, "TIME %s\n", asctime (utc)) ; */
1180
1181 /* 1st step */
1182 res= STV_Interrupt() ; /* Reset Display */
1183 usleep( delay) ;
1184 tcflush(fd, TCIOFLUSH);
1185
1186 res= STV_MenueDateTime( delay) ;
1187 usleep( delay) ;
1188 res= STV_MenueDateTime( delay) ; /* This not an error */
1189 usleep( delay) ;
1190
1191 for( i=0 ; i< 13 ; i++) { /* Reset Month menu to the lef most position */
1192 res= STV_LRRotaryDecrease() ;
1193 usleep( delay) ;
1194 }
1195
1196 for( i=0 ; i< utm.months ; i++) { /* Set Month menu */
1197 res= STV_LRRotaryIncrease() ;
1198 usleep( delay) ;
1199 tcflush(fd, TCIOFLUSH);
1200 }
1201 res= STV_AKey() ; /* Press the Parameter button */
1202 usleep( delay) ;
1203 tcflush(fd, TCIOFLUSH);
1204
1205 for( i=0 ; i< 32 ; i++) { /* Reset Day menu to the lef most position */
1206 res= STV_LRRotaryDecrease() ;
1207 usleep( delay) ;
1208 tcflush(fd, TCIOFLUSH);
1209 }
1210
1211 for( i= 0; i< utm.days-1 ; i++) { /* Set Day menu -1? */
1212 res= STV_LRRotaryIncrease() ;
1213 usleep( delay) ;
1214 tcflush(fd, TCIOFLUSH);
1215 }
1216 res= STV_AKey() ; /* Press the Parameter button */
1217 usleep( delay) ;
1218 tcflush(fd, TCIOFLUSH);
1219
1220 for( i=0 ; i< 128 ; i++) { /* Reset Year menu to the lef most position, ATTENTION */
1221 res= STV_LRRotaryDecrease() ;
1222
1223 usleep( delay) ; /* sleep a 1/100 second */
1224 tcflush(fd, TCIOFLUSH);
1225 }
1226
1227 /* JM: Is this how you want not? Please verify the code! */
1228 int ymenu = utm.years % 100;
1229
1230 for( i=0 ; i< ymenu ; i++) { /* Set Year menu */
1231 res= STV_LRRotaryIncrease() ;
1232 usleep( delay) ;
1233 tcflush(fd, TCIOFLUSH);
1234 }
1235 res= STV_AKey() ; /* Press the Parameter button */
1236 usleep( delay) ;
1237 tcflush(fd, TCIOFLUSH);
1238
1239 for( i=0 ; i< 25 ; i++) { /* Reset Hour menu to the lef most position, ATTENTION */
1240 res= STV_LRRotaryDecrease() ;
1241 usleep( delay) ;
1242 tcflush(fd, TCIOFLUSH);
1243 }
1244 for( i=0 ; i< utm.hours ; i++) { /* Set Hour menu */
1245 res= STV_LRRotaryIncrease() ;
1246 usleep( delay) ;
1247 tcflush(fd, TCIOFLUSH);
1248 }
1249 res= STV_AKey() ; /* Press the Parameter button */
1250 usleep( delay) ;
1251 tcflush(fd, TCIOFLUSH);
1252
1253 for( i=0 ; i< 61 ; i++) { /* Reset Minute menu to the lef most position, ATTENTION */
1254 res= STV_LRRotaryDecrease() ;
1255 usleep( delay) ;
1256 tcflush(fd, TCIOFLUSH);
1257 }
1258 for( i=0 ; i< utm.minutes ; i++) { /* Set Minute menu */
1259 res= STV_LRRotaryIncrease() ;
1260 usleep( delay) ;
1261 tcflush(fd, TCIOFLUSH);
1262 }
1263 res= STV_AKey() ; /* Press the Parameter button */
1264 tcflush(fd, TCIOFLUSH);
1265 for( i=0 ; i< 5 ; i++) { /* Reset Seconds menu to the lef most position, ATTENTION */
1266 res= STV_LRRotaryDecrease() ;
1267 usleep( delay) ;
1268 tcflush(fd, TCIOFLUSH);
1269 }
1270
1271 if ( utm.seconds < 15) {
1272 turn= 0 ;
1273 } else if ( utm.seconds < 30) {
1274 turn= 1 ;
1275 } else if ( utm.seconds < 45) {
1276 turn= 2 ;
1277 } else {
1278 turn= 3 ;
1279 }
1280
1281 for( i=0 ; i< turn ; i++) { /* Set Seconds menu, steps of 15 seconds */
1282 res= STV_LRRotaryIncrease() ;
1283 usleep( delay) ;
1284 tcflush(fd, TCIOFLUSH);
1285 }
1286 res= STV_AKey() ; /* Press the Parameter button */
1287 usleep( delay) ;
1288 tcflush(fd, TCIOFLUSH);
1289
1290 res= STV_BKey() ; /* Press the Parameter button */
1291 usleep( delay) ;
1292 tcflush(fd, TCIOFLUSH);
1293 res= STV_Interrupt() ;
1294 return 0 ;
1295}
1296#endif
1297
1298int STV_MenueDateTime( int delay) {
1299
1300 int i ;
1301 int res ;
1302
1303 res= STV_MenueSetup( delay) ;
1304 usleep( delay) ;
1305 res= STV_BKey() ; /* Press the Value button */
1306 usleep( delay) ;
1307
1308 for( i=0 ; i< 8 ; i++) { /* Reset Date menu to the lef most position */
1309
1310 res= STV_UDRotaryDecrease() ;
1311 usleep( delay) ;
1312 tcflush(fd, TCIOFLUSH);
1313 }
1314 return 0 ;
1315}
1316
1317int STV_MenueSetup( int delay) {
1318
1319 int i ;
1320 int res ;
1321
1322 res= STV_Setup() ; /* Change to Setup */
1323 usleep( delay) ;
1324
1325 for( i=0 ; i< 16 ; i++) { /* Reset Setup menu to the lef most position */
1326 res= STV_UDRotaryDecrease() ;
1327 usleep( delay) ;
1328 tcflush(fd, TCIOFLUSH);
1329 }
1330 return 0 ;
1331}
1332
1333int STV_Connect( char *device, int baud) {
1334
1335
1336 /*fprintf( stderr, "STV_Connect\n") ; */
1337 if(( fd= init_serial( device, baud, 8, 0, 1))== -1) {
1338 fprintf(stderr, "Error on port %s, %s\n", device, strerror(errno)) ;
1339 return -1 ;
1340 }
1341
1342 return fd ;
1343}
1344
1345/******************************************************************************
1346 * shutdown_serial(..)
1347 ******************************************************************************
1348 * Restores terminal settings of open serial port device and close the file.
1349 * Arguments:
1350 * fd: file descriptor of open serial port device.
1351 *****************************************************************************/
1352void
1353shutdown_serial(int fd)
1354{
1355 if (fd > 0) {
1356 if (tcsetattr(fd, TCSANOW, &orig_tty_setting) < 0) {
1357 perror("shutdown_serial: can't restore serial device's terminal settings.");
1358 }
1359 close(fd);
1360 }
1361}
1362/******************************************************************************
1363 * init_serial(..)
1364 ******************************************************************************
1365 * Opens and initializes a serial device and returns it's file descriptor.
1366 * Arguments:
1367 * device_name : device name string of the device to open (/dev/ttyS0, ...)
1368 * bit_rate : bit rate
1369 * word_size : number of data bits, 7 or 8, USE 8 DATA BITS with modbus
1370 * parity : 0=no parity, 1=parity EVEN, 2=parity ODD
1371 * stop_bits : number of stop bits : 1 or 2
1372 * Return:
1373 * file descriptor of successfully opened serial device
1374 * or -1 in case of error.
1375 *****************************************************************************/
1376int
1377init_serial(char *device_name, int bit_rate, int word_size,
1378 int parity, int stop_bits)
1379{
1380 int fd;
1381 char *msg;
1382
1383 /* open serial device */
1384 fd = open(device_name, O_RDWR | O_NOCTTY);
1385 if (fd < 0) {
1386 if (asprintf(&msg, "init_serial: open %s failed", device_name) < 0)
1387 perror(NULL);
1388 else
1389 perror(msg);
1390
1391 return -1;
1392 }
1393
1394 /* save current tty settings */
1395 if (tcgetattr(fd, &orig_tty_setting) < 0) {
1396 perror("init_serial: can't get terminal parameters.");
1397 return -1;
1398 }
1399
1400
1401 /* Control Modes */
1402 /* Set bps rate */
1403 int bps;
1404 switch (bit_rate) {
1405 case 0:
1406 bps = B0;
1407 break;
1408 case 50:
1409 bps = B50;
1410 break;
1411 case 75:
1412 bps = B75;
1413 break;
1414 case 110:
1415 bps = B110;
1416 break;
1417 case 134:
1418 bps = B134;
1419 break;
1420 case 150:
1421 bps = B150;
1422 break;
1423 case 200:
1424 bps = B200;
1425 break;
1426 case 300:
1427 bps = B300;
1428 break;
1429 case 600:
1430 bps = B600;
1431 break;
1432 case 1200:
1433 bps = B1200;
1434 break;
1435 case 1800:
1436 bps = B1800;
1437 break;
1438 case 2400:
1439 bps = B2400;
1440 break;
1441 case 4800:
1442 bps = B4800;
1443 break;
1444 case 9600:
1445 bps = B9600;
1446 break;
1447 case 19200:
1448 bps = B19200;
1449 break;
1450 case 38400:
1451 bps = B38400;
1452 break;
1453 case 57600:
1454 bps = B57600;
1455 break;
1456 case 115200:
1457 bps = B115200;
1458 break;
1459 case 230400:
1460 bps = B230400;
1461 break;
1462 default:
1463 if (asprintf(&msg, "init_serial: %d is not a valid bit rate.", bit_rate) < 0)
1464 perror(NULL);
1465 else
1466 perror(msg);
1467 return -1;
1468 }
1469 if ((cfsetispeed(&tty_setting, bps) < 0) ||
1470 (cfsetospeed(&tty_setting, bps) < 0))
1471 {
1472 perror("init_serial: failed setting bit rate.");
1473 return -1;
1474 }
1475
1476 /* Control Modes */
1477 /* set no flow control word size, parity and stop bits. */
1478 /* Also don't hangup automatically and ignore modem status. */
1479 /* Finally enable receiving characters. */
1480 tty_setting.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | HUPCL | CRTSCTS);
1481 /* #ifdef CBAUDEX */
1482 /*tty_setting.c_cflag &= ~(CBAUDEX); */
1483 /*#endif */
1484 /*#ifdef CBAUDEXT */
1485 /*tty_setting.c_cflag &= ~(CBAUDEXT); */
1486 /*#endif */
1487 tty_setting.c_cflag |= (CLOCAL | CREAD);
1488
1489 /* word size */
1490 switch (word_size) {
1491 case 5:
1492 tty_setting.c_cflag |= CS5;
1493 break;
1494 case 6:
1495 tty_setting.c_cflag |= CS6;
1496 break;
1497 case 7:
1498 tty_setting.c_cflag |= CS7;
1499 break;
1500 case 8:
1501 tty_setting.c_cflag |= CS8;
1502 break;
1503 default:
1504
1505 fprintf( stderr, "Default\n") ;
1506 if (asprintf(&msg,
1507 "init_serial: %d is not a valid data bit count.",
1508 word_size) < 0)
1509 perror(NULL);
1510 else
1511 perror(msg);
1512
1513 return -1;
1514 }
1515
1516 /* parity */
1517 switch (parity) {
1518 case PARITY_NONE:
1519 break;
1520 case PARITY_EVEN:
1521 tty_setting.c_cflag |= PARENB;
1522 break;
1523 case PARITY_ODD:
1524 tty_setting.c_cflag |= PARENB | PARODD;
1525 break;
1526 default:
1527
1528 fprintf( stderr, "Default1\n") ;
1529 if (asprintf(&msg,
1530 "init_serial: %d is not a valid parity selection value.",
1531 parity) < 0)
1532 perror(NULL);
1533 else
1534 perror(msg);
1535
1536 return -1;
1537 }
1538
1539 /* stop_bits */
1540 switch (stop_bits) {
1541 case 1:
1542 break;
1543 case 2:
1544 tty_setting.c_cflag |= CSTOPB;
1545 break;
1546 default:
1547 fprintf( stderr, "Default2\n") ;
1548 if (asprintf(&msg,
1549 "init_serial: %d is not a valid stop bit count.",
1550 stop_bits) < 0)
1551 perror(NULL);
1552 else
1553 perror(msg);
1554
1555 return -1;
1556 }
1557 /* Control Modes complete */
1558
1559 /* Ignore bytes with parity errors and make terminal raw and dumb. */
1560 tty_setting.c_iflag &= ~(PARMRK | ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON | IXANY);
1561 tty_setting.c_iflag |= INPCK | IGNPAR | IGNBRK;
1562
1563 /* Raw output. */
1564 tty_setting.c_oflag &= ~(OPOST | ONLCR);
1565
1566 /* Local Modes */
1567 /* Don't echo characters. Don't generate signals. */
1568 /* Don't process any characters. */
1569 tty_setting.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IEXTEN | NOFLSH | TOSTOP);
1570 tty_setting.c_lflag |= NOFLSH;
1571
1572 /* blocking read until 1 char arrives */
1573 tty_setting.c_cc[VMIN] = 1;
1574 tty_setting.c_cc[VTIME] = 0;
1575
1576 /* now clear input and output buffers and activate the new terminal settings */
1577 tcflush(fd, TCIOFLUSH);
1578 if (tcsetattr(fd, TCSANOW, &tty_setting)) {
1579 perror("init_serial: failed setting attributes on serial port.");
1580 shutdown_serial(fd);
1581 return -1;
1582 }
1583 return fd;
1584}
Note: See TracBrowser for help on using the repository browser.