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
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.
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.
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
38 #include <libnova/libnova.h>
65 int STV_RequestImage(
int compression,
int buffer,
int x_offset,
int y_offset,
int *length,
int *lines,
int image[][320],
78 int STV_DecompressData(
unsigned char *data,
int *values,
int length,
int expected_n_values);
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);
195 unsigned char buf[1024];
196 unsigned int value[21];
207 fprintf(stderr,
" STV_RequestImageInfo error %d\n", res);
229 fprintf(stderr,
"STV_RequestImageInfo: expected REQUEST_IMAGE_INFO, received %d, try again\n", buf[1]);
234 length = buf[3] * 0x100 + buf[2];
238 for (i = 6; i < length; i += 2)
340 image_info->
height = value[1];
341 image_info->
width = value[2];
342 image_info->
top = value[3];
343 image_info->
left = value[4];
347 if ((value[5] >= 100) && (value[5] <= 60000))
349 image_info->
exposure = ((float)value[5]) * 0.01;
351 else if ((value[5] >= 60001) && (value[5] <= 60999))
353 image_info->
exposure = ((float)value[5] - 60000.) * .001;
357 fprintf(stderr,
"Error Exposure time %d\n", value[5]);
379 image_info->
hours += 12;
382 if ((value[13] & 0x8000) == 0x8000)
384 image_info->
ccdTemp = (float)(0xffff - value[13]) / 100.;
388 image_info->
ccdTemp = (float)value[13] / 100.;
391 image_info->
siteID = value[14];
392 image_info->
eGain = value[15];
394 image_info->
range = value[17];
396 image_info->
ccdTop = value[19];
397 image_info->
ccdLeft = value[20];
436 unsigned char buf[0xffff];
438 int data[] = { 0, y_offset, *length,
buffer };
455 if (x_offset > image_info->
height)
457 x_offset = image_info->
height;
459 XOFF = image_info->
top + x_offset;
461 if (y_offset > image_info->
width)
463 y_offset = image_info->
width;
465 data[1] = image_info->
left + y_offset;
467 if (*length > image_info->
width - y_offset)
469 *length = image_info->
width - y_offset;
473 if (*lines > image_info->
height - x_offset)
475 *lines = image_info->
height - x_offset;
480 for (j = 0; j < *lines; j++)
486 fprintf(stderr,
"STV_RequestImage: Calling STV_RequestImageData failed %d\n", n_values);
491 for (i = 0; i < n_values; i++)
493 image[j][i] = values[i];
509 for (i = 0; i < n_values; i++)
526 unsigned char buf[0xffff];
530 if (compression ==
ON)
535 fprintf(stderr,
"STV_RequestImageData: could not write\n");
548 fprintf(stderr,
"STV_RequestImageData: expected REQUEST_COMPRESSED_IMAGE_DATA, received %2x\n",
555 data_length = (int)buf[3] * 0x100 + (
int)buf[2];
559 n_values = -n_values;
560 fprintf(stderr,
"SEVERE ERROR on Line %d, pixel position=%d\n", j, n_values);
564 if (n_values == length)
570 fprintf(stderr,
"SEVERE Error: Length not equal, Line: %d, %d != %d, data %2x %2x, values %d, %d\n", j,
571 n_values, length, buf[6 + length - 2], buf[6 + length - 1], values[n_values - 2],
572 values[n_values - 1]);
578 fprintf(stderr,
"Error: waiting for data on the serial port at line %d\n", j);
596 fprintf(stderr,
"STV_RequestImageData: expected REQUEST_IMAGE_DATA, received %2x\n",
603 data_length = (int)buf[3] * 0x100 + (
int)buf[2];
605 for (i = 0; i < data_length; i += 2)
609 return data_length / 2;
614 fprintf(stderr,
"Error: waiting for data on the serial port at line %d\n", j);
620 fprintf(stderr,
"STV_RequestImageData: error writing %d\n", res);
639 if (((data[i] & 0xc0)) == 0x80)
642 if ((data[i] & 0x20) == 0x20)
646 -((int)(((~data[i] & 0x1f)) * 0x100) + (((
int)(~data[i + 1])) & 0xff)) - 1;
650 value = (int)((data[i] & 0x1f) * 0x100) + (
int)(data[i + 1]);
654 values[n_values++] = base;
657 else if (((data[i] & 0x80)) == 0)
660 if ((data[i] & 0x40) == 0x40)
663 value = -(int)((~(data[i])) & 0x3f) - 1;
667 value = (int)(data[i] & 0x3f);
673 if ((value == 0) && (n_values == expected_n_values))
680 values[n_values++] = base;
684 else if (((data[i] & 0xc0)) == 0xc0)
690 value = 4 * ((int)((data[i] & 0x3f) * 0x100) + (
int)(data[i + 1]));
694 values[n_values++] = value;
701 fprintf(stderr,
"Unknown compression case: %2x, length %d, i=%d\n", data[i], length, i);
710 int data[] = {
TRUE };
717 int data[] = {
FALSE };
724 tcflush(
fd, TCIOFLUSH);
730 int data[] = { status };
751 int data[] = { 0x06, 0x06, 0x06 };
758 unsigned char buf[1024];
767 fprintf(stderr,
"STV_BufferStatus: Error requesting buffer status: %d\n",
buffer);
778 fprintf(stderr,
"STV_BufferStatus: Error reading: %d\n", res);
808 fprintf(stderr,
"STV_BufferStatus: unexpected cmd byte received %d\n", buf[1]);
816 fprintf(stderr,
"STV_BufferStatus DISPLAY_ECHO received, try again\n");
845 if ((trb = read(
fd, (
char *)(buf + pos), 1)) == -1)
847 fprintf(stderr,
"Error, %s\n", strerror(
errno));
887 for (k = 0; k < j; k++)
894 fprintf(stderr,
"Not a packet: length: %d >%s<\n", j,
tracking_buf);
900 if ((buf[0] == 0xa5) && (pos == 6))
904 length = (int)buf[3] * 0x100 + (
int)buf[2];
910 while (pos < 6 + length + 2)
915 if ((trb = read(
fd, (
char *)(buf + pos), (6 + length + 2) - pos)) == -1)
917 fprintf(stderr,
"STV_ReceivePacket: Error reading at serial port, %s\n", strerror(
errno));
928 fprintf(stderr,
"STV_ReceivePacket: Header check failed\n");
934 for (i = 0; i < 6; i++)
938 fprintf(stderr,
"STV_ReceivePacket: pos= %d, saw 0xa5 at %d\n", pos, i);
945 fprintf(stderr,
"STV_ReceivePacket: NO 0xa5 until pos= %d\n", pos);
960 for (i = 0; i < 24; i++)
962 display1[i] = buf[i + 6];
963 if (display1[i] == 0)
967 display2[i] = buf[i + 30];
968 if (display2[i] == 0)
980 if ((res = strncmp(
"CCD Temp.", display2, 9)) == 0)
983 res = sscanf(display2,
"CCD Temp. %f", &t);
993 int sum = buf[0] + buf[1] + buf[2] + buf[3];
998 fprintf(stderr,
"STV_CheckHeaderSum: Wrong start byte, skipping\n");
1004 fprintf(stderr,
"STV_CheckHeaderSum: NOK: %d==%d\n", sum, sumbuf);
1022 fprintf(stderr,
"STV_CheckDataSum: No data present\n");
1027 for (j = 0; j < n; j++)
1029 sum += (int)buf[6 + j];
1035 fprintf(stderr,
"DATA SUM NOK: %d !=%d\n", sum, sumbuf);
1046 fprintf(stderr,
"\nHEADER: %d bytes ", n);
1047 for (i = 0; i < n; i++)
1051 fprintf(stderr,
"\nDATA : ");
1053 fprintf(stderr,
"%d:0x%2x<>%c< >>", i, (
unsigned char)buf[i], (
unsigned char)buf[i]);
1056 fprintf(stderr,
"\n");
1065 fprintf(stderr,
"\nHEADER: %d bytes ", n);
1066 for (i = 0; i < n; i++)
1070 fprintf(stderr,
"\nDATA : ");
1072 fprintf(stderr,
"%c", (
unsigned char)buf[i]);
1074 fprintf(stderr,
"\n");
1089 buf[0] = (
unsigned char)0xa5;
1090 buf[1] = (
unsigned char)
cmd;
1091 buf[2] = (
unsigned char)2 * n;
1092 buf[3] = (
unsigned char)0x00;
1094 sum = buf[0] + buf[1] + buf[2] + buf[3];
1095 buf[4] = (
unsigned char)sum % 0x100;
1096 buf[5] = (
unsigned char)(sum / 0x100);
1103 for (j = 0; j < 2 * n; j += 2)
1105 buf[6 + j] = (
unsigned char)(data[j / 2] % 0x100);
1106 buf[7 + j] = (
unsigned char)(data[j / 2] / 0x100);
1110 for (j = 0; j < 2 * n; j++)
1112 if ((
int)buf[6 + j] < 0)
1114 sum = sum + 0xff + (int)buf[6 + j] + 1;
1118 sum = sum + (int)buf[6 + j];
1121 buf[6 + 2 * n] = (
unsigned char)(sum % 0x10000);
1122 buf[7 + 2 * n] = (
unsigned char)(sum / 0x100);
1127 fprintf(stderr,
"STV_SendPacket: corrupt header\n");
1133 fprintf(stderr,
"STV_SendPacket: corrupt data\n");
1144 int bytesWritten = 0;
1149 if ((bytesWritten = write(
fd, buf, nbytes)) == -1)
1151 fprintf(stderr,
"STV_portWrite: Error writing at serial port, %s\n", strerror(
errno));
1155 if (bytesWritten < 0)
1157 fprintf(stderr,
"STV_portWrite: Error writing\n");
1162 buf += bytesWritten;
1163 nbytes -= bytesWritten;
1173 unsigned char ackseq[] = { 0xa5, 0x06, 0x00, 0x00, 0xab, 0x00 };
1175 for (i = 0; i < 6; i++)
1177 if (buf[i] != ackseq[i])
1187 return (
unsigned int)high_byte * (
unsigned int)0x100 + (
unsigned int)low_byte;
1193 return (x >> (p + 1 - n)) & ~(~0 << n);
1201 fprintf(stderr,
"STV_PrintBits:\n");
1205 fprintf(stderr,
"54321098 76543210\n");
1209 fprintf(stderr,
"76543210\n");
1212 for (i = n; i > 0; i--)
1214 if ((i == 8) && (n > 8))
1216 fprintf(stderr,
" ");
1220 fprintf(stderr,
"0");
1224 fprintf(stderr,
"1");
1227 fprintf(stderr,
"\n");
1235 unsigned char buf[1024];
1238 tcflush(
fd, TCIOFLUSH);
1243 for (i = 0; i < 100; i++)
1246 tcflush(
fd, TCIOFLUSH);
1264 if ((res != 62) || (i++ > 100))
1284 tcflush(
fd, TCIOFLUSH);
1297 if ((times == NULL) || ((res = strlen(times)) == 0))
1298 ln_get_date_from_sys(&utm);
1303 fprintf(stderr,
"Bad time string %s\n", times);
1313 tcflush(
fd, TCIOFLUSH);
1320 for (i = 0; i < 13; i++)
1326 for (i = 0; i < utm.months; i++)
1330 tcflush(
fd, TCIOFLUSH);
1334 tcflush(
fd, TCIOFLUSH);
1336 for (i = 0; i < 32; i++)
1340 tcflush(
fd, TCIOFLUSH);
1343 for (i = 0; i < utm.days - 1; i++)
1347 tcflush(
fd, TCIOFLUSH);
1351 tcflush(
fd, TCIOFLUSH);
1353 for (i = 0; i < 128; i++)
1358 tcflush(
fd, TCIOFLUSH);
1362 int ymenu = utm.years % 100;
1364 for (i = 0; i < ymenu; i++)
1368 tcflush(
fd, TCIOFLUSH);
1372 tcflush(
fd, TCIOFLUSH);
1374 for (i = 0; i < 25; i++)
1378 tcflush(
fd, TCIOFLUSH);
1380 for (i = 0; i < utm.hours; i++)
1384 tcflush(
fd, TCIOFLUSH);
1388 tcflush(
fd, TCIOFLUSH);
1390 for (i = 0; i < 61; i++)
1394 tcflush(
fd, TCIOFLUSH);
1396 for (i = 0; i < utm.minutes; i++)
1400 tcflush(
fd, TCIOFLUSH);
1403 tcflush(
fd, TCIOFLUSH);
1404 for (i = 0; i < 5; i++)
1408 tcflush(
fd, TCIOFLUSH);
1411 if (utm.seconds < 15)
1415 else if (utm.seconds < 30)
1419 else if (utm.seconds < 45)
1428 for (i = 0; i < turn; i++)
1432 tcflush(
fd, TCIOFLUSH);
1436 tcflush(
fd, TCIOFLUSH);
1440 tcflush(
fd, TCIOFLUSH);
1455 for (i = 0; i < 8; i++)
1460 tcflush(
fd, TCIOFLUSH);
1473 for (i = 0; i < 16; i++)
1477 tcflush(
fd, TCIOFLUSH);
1487 fprintf(stderr,
"Error on port %s, %s\n",
device, strerror(
errno));
1507 perror(
"shutdown_serial: can't restore serial device's terminal settings.");
1526 int init_serial(
char *device_name,
int bit_rate,
int word_size,
int parity,
int stop_bits)
1532 fd = open(device_name, O_RDWR | O_NOCTTY);
1535 if (asprintf(&msg,
"init_serial: open %s failed", device_name) < 0)
1546 perror(
"init_serial: can't get terminal parameters.");
1613 if (asprintf(&msg,
"init_serial: %d is not a valid bit rate.", bit_rate) < 0)
1621 perror(
"init_serial: failed setting bit rate.");
1629 tty_setting.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD | HUPCL | CRTSCTS);
1655 fprintf(stderr,
"Default\n");
1656 if (asprintf(&msg,
"init_serial: %d is not a valid data bit count.", word_size) < 0)
1677 fprintf(stderr,
"Default1\n");
1678 if (asprintf(&msg,
"init_serial: %d is not a valid parity selection value.", parity) < 0)
1695 fprintf(stderr,
"Default2\n");
1696 if (asprintf(&msg,
"init_serial: %d is not a valid stop bit count.", stop_bits) < 0)
1706 tty_setting.c_iflag &= ~(PARMRK | ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON | IXANY);
1715 tty_setting.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IEXTEN | NOFLSH | TOSTOP);
1723 tcflush(
fd, TCIOFLUSH);
1726 perror(
"init_serial: failed setting attributes on serial port.");
Implementations for common driver routines.
int extractISOTime(const char *timestr, struct ln_date *iso_date)
Extract ISO 8601 time and store it in a tm struct.
std::vector< uint8_t > buffer
int STV_ReceivePacket(unsigned char *buf, int mode)
int STV_CheckHeaderSum(unsigned char *buf)
int STV_PrintBuffer(unsigned char *buf, int n)
int STV_BufferStatus(int buffer)
int STV_MenueDateTime(int delay)
int STV_DownloadComplete(void)
int STV_RequestImageInfo(int buffer, IMAGE_INFO *image_info)
int STV_RequestImageData(int compression, int *data, int j, int length, int *values)
int STV_DecompressData(unsigned char *data, int *values, int length, int expected_n_values)
int STV_Connect(char *device, int baud)
int init_serial(char *device_name, int bit_rate, int word_size, int parity, int stop_bits)
int STV_RequestImage(int compression, int buffer, int x_offset, int y_offset, int *length, int *lines, int image[][320], IMAGE_INFO *image_info)
int STV_CheckAck(unsigned char *buf)
int STV_SetDateTime(char *times)
unsigned int STV_RecombineInt(unsigned char low_byte, unsigned char high_byte)
int STV_MenueSetup(int delay)
struct termios tty_setting
int STV_CheckDataSum(unsigned char *data)
struct termios orig_tty_setting
int STV_LRRotaryIncrease(void)
int STV_PrintBufferAsText(unsigned char *buf, int n)
unsigned int STV_GetBits(unsigned int x, int p, int n)
int STV_LRRotaryDecrease(void)
void shutdown_serial(int fd)
int STV_portWrite(char *buf, int nbytes)
int STV_TerminateTXDisplay(void)
int STV_DownloadAll(void)
double STV_SetCCDTemperature(double set_value)
void STV_PrintBits(unsigned int x, int n)
int STV_MenueCCDTemperature(int delay)
void ISUpdateDisplay(int buffer, int line)
int STV_UDRotaryDecrease(void)
int STV_UDRotaryIncrease(void)
int STV_SendPacket(int cmd, int *data, int n)
#define UD_ROTARY_INCREASE_PATTERN
#define IMAGE_KEY_PATTERN
#define UD_ROTARY_DECREASE_PATTERN
#define REQUEST_BUFFER_STATUS
#define LR_ROTARY_INCREASE_PATTERN
#define REQUEST_DOWNLOAD_ALL
#define REQUEST_IMAGE_DATA
#define REQUEST_IMAGE_INFO
#define LR_ROTARY_DECREASE_PATTERN
#define FOCUS_KEY_PATTERN
#define DOWNLOAD_COMPLETE
#define REQUEST_COMPRESSED_IMAGE_DATA
#define MONITOR_KEY_PATTERN
#define TRACK_KEY_PATTERN
#define FILEOPS_KEY_PATTERN
#define DISPLAY_KEY_PATTERN
#define SETUP_KEY_PATTERN
#define ID_DATETIME_INVALID
#define ID_DATETIME_VALID
#define ID_SCOPE_REFLECTOR
#define ID_SCOPE_REFRACTOR