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 | |
---|
48 | extern int fd ; |
---|
49 | extern char tracking_buf[] ; |
---|
50 | struct termios orig_tty_setting; /* old serial port setting to restore on close */ |
---|
51 | struct 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) ; */ |
---|
59 | void ISUpdateDisplay( int buffer, int line) ; |
---|
60 | |
---|
61 | int STV_portWrite( char *buf, int nbytes) ; |
---|
62 | int STV_TXDisplay( void) ; |
---|
63 | int STV_TerminateTXDisplay( void) ; |
---|
64 | int STV_FileStatus( int) ; |
---|
65 | int STV_DownloadComplete( void) ; |
---|
66 | int STV_RequestImage( int compression, int buffer, int x_offset, int y_offset, int *length, int *lines, int image[][320], IMAGE_INFO *image_info) ; |
---|
67 | int STV_RequestImageData( int compression, int *data, int j, int length, int *values) ; |
---|
68 | int STV_Download( void) ; |
---|
69 | int STV_DownloadAll( void) ; |
---|
70 | int STV_RequestAck( void) ; |
---|
71 | int STV_CheckHeaderSum( unsigned char *buf) ; |
---|
72 | int STV_CheckDataSum( unsigned char *data) ; |
---|
73 | int STV_PrintBuffer( unsigned char *buf, int n ) ; |
---|
74 | int STV_PrintBufferAsText( unsigned char *buf, int n ) ; |
---|
75 | int STV_CheckAck( unsigned char *buf) ; |
---|
76 | int STV_SendPacket( int cmd, int *data, int n) ; |
---|
77 | int STV_ReceivePacket( unsigned char *buf, int mode) ; |
---|
78 | int STV_DecompressData( unsigned char *data, int *values, int length, int expected_n_values) ; |
---|
79 | int STV_BufferStatus( int buffer) ; |
---|
80 | void STV_PrintBits( unsigned int x, int n) ; |
---|
81 | |
---|
82 | unsigned int STV_RecombineInt( unsigned char low_byte, unsigned char high_byte) ; |
---|
83 | unsigned int STV_GetBits( unsigned int x, int p, int n) ; |
---|
84 | |
---|
85 | int STV_MenueSetup( int delay) ; |
---|
86 | int STV_MenueDateTime( int delay) ; |
---|
87 | int STV_MenueCCDTemperature( int delay) ; |
---|
88 | |
---|
89 | typedef struct { |
---|
90 | |
---|
91 | double ccd_temperature ; |
---|
92 | |
---|
93 | } DISPLAY_INFO ; |
---|
94 | |
---|
95 | DISPLAY_INFO di ; |
---|
96 | |
---|
97 | |
---|
98 | /* STV Buttons */ |
---|
99 | |
---|
100 | int STV_LRRotaryDecrease(void) { |
---|
101 | int data[]={LR_ROTARY_DECREASE_PATTERN} ; |
---|
102 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; |
---|
103 | } |
---|
104 | |
---|
105 | int STV_LRRotaryIncrease(void) { |
---|
106 | int data[]={ LR_ROTARY_INCREASE_PATTERN} ; |
---|
107 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; |
---|
108 | } |
---|
109 | |
---|
110 | int STV_UDRotaryDecrease(void) { |
---|
111 | int data[]={UD_ROTARY_DECREASE_PATTERN} ; |
---|
112 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; |
---|
113 | } |
---|
114 | |
---|
115 | int STV_UDRotaryIncrease(void) { |
---|
116 | int data[]={UD_ROTARY_INCREASE_PATTERN} ; |
---|
117 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; |
---|
118 | } |
---|
119 | |
---|
120 | int STV_AKey(void) { /* Parameter button */ |
---|
121 | int data[]={A_KEY_PATTERN} ; |
---|
122 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; |
---|
123 | } |
---|
124 | |
---|
125 | int STV_BKey(void) { /* Value Button */ |
---|
126 | int data[]={ B_KEY_PATTERN} ; |
---|
127 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; |
---|
128 | } |
---|
129 | |
---|
130 | int STV_Setup(void) { |
---|
131 | int data[]={SETUP_KEY_PATTERN} ; |
---|
132 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1); |
---|
133 | } |
---|
134 | |
---|
135 | int STV_Interrupt(void) { |
---|
136 | int data[]={INT_KEY_PATTERN} ; |
---|
137 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; |
---|
138 | } |
---|
139 | |
---|
140 | int STV_Focus(void) { |
---|
141 | int data[]= {FOCUS_KEY_PATTERN} ; |
---|
142 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; |
---|
143 | } |
---|
144 | |
---|
145 | int STV_Image(void) { |
---|
146 | int data[]={IMAGE_KEY_PATTERN} ; |
---|
147 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; |
---|
148 | } |
---|
149 | |
---|
150 | int STV_Monitor(void) { |
---|
151 | int data[]={MONITOR_KEY_PATTERN} ; |
---|
152 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; |
---|
153 | } |
---|
154 | |
---|
155 | int STV_Calibrate(void) { |
---|
156 | int data[]={CAL_KEY_PATTERN} ; |
---|
157 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; |
---|
158 | } |
---|
159 | |
---|
160 | int STV_Track(void) { |
---|
161 | int data[]={TRACK_KEY_PATTERN} ; |
---|
162 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; |
---|
163 | } |
---|
164 | |
---|
165 | int STV_Display(void) { |
---|
166 | int data[]={DISPLAY_KEY_PATTERN} ; |
---|
167 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; |
---|
168 | } |
---|
169 | |
---|
170 | int STV_FileOps(void) { |
---|
171 | int data[]={FILEOPS_KEY_PATTERN} ; |
---|
172 | return STV_SendPacket(SEND_KEY_PATTERN, data, 1) ; |
---|
173 | } |
---|
174 | |
---|
175 | int 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 | |
---|
204 | AGAINI: 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 | |
---|
400 | int 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 | |
---|
479 | int 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 | |
---|
497 | AGAINC: 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 | |
---|
535 | AGAINU: 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 | } |
---|
564 | int 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 | |
---|
636 | int STV_TXDisplay(void) { |
---|
637 | |
---|
638 | int data[]={TRUE} ; |
---|
639 | return STV_SendPacket( DISPLAY_ECHO, data, 1); |
---|
640 | } |
---|
641 | |
---|
642 | int 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 | |
---|
655 | int STV_FileStatus(int status) { |
---|
656 | |
---|
657 | int data[]= {status} ; |
---|
658 | return STV_SendPacket( FILE_STATUS, data, 1); |
---|
659 | } |
---|
660 | |
---|
661 | int STV_DownloadComplete(void) { |
---|
662 | |
---|
663 | return STV_SendPacket( DOWNLOAD_COMPLETE, NULL, 0); |
---|
664 | } |
---|
665 | |
---|
666 | int STV_Download(void) { |
---|
667 | |
---|
668 | return STV_SendPacket( REQUEST_DOWNLOAD, NULL, 0) ; |
---|
669 | } |
---|
670 | |
---|
671 | int STV_DownloadAll(void) { |
---|
672 | |
---|
673 | return STV_SendPacket( REQUEST_DOWNLOAD_ALL, NULL, 0); |
---|
674 | } |
---|
675 | |
---|
676 | int 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 | |
---|
682 | int 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 | |
---|
698 | AGAIN: 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 */ |
---|
738 | int 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 | |
---|
884 | int 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 | |
---|
903 | int 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 | |
---|
932 | int 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 | } |
---|
949 | int 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 | |
---|
967 | int 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 | |
---|
1025 | int 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 | |
---|
1050 | int 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 | |
---|
1064 | unsigned 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 | |
---|
1069 | unsigned 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 | |
---|
1074 | void 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 | |
---|
1102 | double 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 | |
---|
1146 | int 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 |
---|
1159 | int 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 | |
---|
1298 | int 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 | |
---|
1317 | int 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 | |
---|
1333 | int 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 | *****************************************************************************/ |
---|
1352 | void |
---|
1353 | shutdown_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 | *****************************************************************************/ |
---|
1376 | int |
---|
1377 | init_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 | } |
---|