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

Last change on this file since 682 was 490, checked in by campagne, 14 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.