1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <ctype.h>
4 #include <string.h>
5 #include <time.h>
6 #include <sys/types.h>
7 #include <termios.h>
8 #include <fcntl.h>
9 #include "dc20_hif.h"
10
11 #define Kb 1024
12
13 /* GLOBAL VARIABLES ***************************************/
14 unsigned char inp_buff[INP_BUFF_SIZE];
15 unsigned char sts_res= 0, sts_bat= 0;
16 unsigned char sts_pic_cnt= 0, sts_pic_rem= 0;
17 unsigned char dc_type= 0x25;
18 unsigned char com_dev[128]= "/dev/cuaa0";
19
20
21 /* LOCAL VARIABLES ****************************************/
22 speed_t com_speed= B9600;
23 long com_baud, baud_save= 9600;
24 struct termios tty_param, old_tty;
25 int com_hdl;
26
27 unsigned char cmd_init[] = { 8, 0x41, 0, 0x96, 0, 0, 0, 0, 0x1A };
28 unsigned char cmd_status[]= { 8, 0x7F, 0, 0, 0, 0, 0, 0, 0x1A };
29 unsigned char cmd_shot[] = { 8, 0x77, 0, 0, 0, 0, 0, 0, 0x1A };
30 unsigned char cmd_ldpic2[]= { 8, 0x51, 0, 0, 1, 0, 0, 0, 0x1A }; /* header + picture */
31 unsigned char cmd_ldpic1[]= { 8, 0x55, 0, 0, 1, 0, 0, 0, 0x1A }; /* header only */
32 unsigned char cmd_thumbn[]= { 8, 0x56, 0, 0, 1, 0, 0, 0, 0x1A };
33 unsigned char cmd_erase[] = { 8, 0x7A, 0, 0, 0, 0, 0, 0, 0x1A };
34 unsigned char cmd_lores[] = { 8, 0x71, 0, 1, 0, 0, 0, 0, 0x1A };
35 unsigned char cmd_hires[] = { 8, 0x71, 0, 0, 0, 0, 0, 0, 0x1A };
36
37 /* LOCAL FUNCTIONS *****************************************/
38
pause(int millisec)39 void pause(int millisec)
40 {
41
42 long wait, goal;
43
44 wait = ( (long) millisec * (long) CLOCKS_PER_SEC + 500) / 1000;
45 goal = wait + (long) clock();
46 while ( goal > (long) clock() )
47 ;
48
49 }
50
51 /* hardware specific functions *****************************/
52
cxmit(unsigned char c)53 void cxmit(unsigned char c)
54 {
55 if (write(com_hdl, &c, 1) != 1)
56 perror("write");
57 }
58
crcv(int * error)59 unsigned char crcv(int *error)
60 {
61 unsigned char c;
62
63 if (read(com_hdl, &c, 1) == 1)
64 return c;
65 else
66 *error+= ERR_NO_DATA;
67
68 return 0xFF;
69 }
70
read_from_com(int nof_bytes)71 int read_from_com(int nof_bytes)
72 {
73 unsigned int i, k, retry= 5;
74 unsigned char chksum;
75
76 while (retry--)
77 {
78 chksum= 0;
79
80 /* i= read(com_hdl, inp_buff, nof_bytes); */
81 for (i= 0; i< nof_bytes; )
82 {
83 if ((k= read(com_hdl, &inp_buff[i], nof_bytes-i)) < 1)
84 break;
85 i+= k;
86 }
87
88 if (i == nof_bytes)
89 {
90
91 for (i= 0; i < nof_bytes; i++)
92 chksum^= inp_buff[i];
93
94 if ( chksum == 0 )
95 return nof_bytes;
96 else
97 i= nof_bytes - 1;
98 }
99
100 if (retry)
101 {
102 cxmit(0xE3);
103 }
104 }
105
106 return i;
107 }
108
set_com_baud(long baud)109 void set_com_baud(long baud)
110 {
111 com_baud= baud;
112
113 switch (baud)
114 {
115 case 9600 : com_speed= B9600; break;
116 case 19200: com_speed= B19200; break;
117 case 38400: com_speed= B38400; break;
118 case 57600: com_speed= B57600; break;
119 case 115200: com_speed= B115200; break;
120 default: com_speed= B9600; baud= 9600;
121 }
122
123 cfsetospeed(&tty_param, com_speed);
124 cfsetispeed(&tty_param, com_speed);
125
126 if (tcsetattr(com_hdl, TCSANOW, &tty_param) == -1)
127 {
128 perror("tcsetattr");
129 }
130 }
131
toggle_baud_rate(void)132 void toggle_baud_rate(void)
133 {
134 if (com_baud > 9600)
135 {
136 baud_save= com_baud;
137 set_com_baud(9600);
138 }
139 else
140 {
141 set_com_baud(baud_save);
142 }
143 }
144
initcom(int com_nr,long baud)145 void initcom(int com_nr, long baud)
146 {
147 switch (com_nr)
148 {
149 case 1: strcpy(com_dev, "/dev/cuaa0") ; break;
150 case 2: strcpy(com_dev, "/dev/cuaa1") ; break;
151 case 3: strcpy(com_dev, "/dev/cuaa2") ; break;
152 case 4: strcpy(com_dev, "/dev/cuaa3") ; break;
153 default: strcpy(com_dev, "/dev/cuaa0") ; break;
154 }
155
156 if ((com_hdl = open(com_dev, O_RDWR)) == -1)
157 {
158 perror("open");
159 fprintf(stderr, "Could not open %s for read/write.\n", com_dev);
160 exit(-1);
161 }
162
163 cfmakeraw(&tty_param);
164 tty_param.c_oflag &= ~CSTOPB;
165 tty_param.c_cflag |= PARENB;
166 tty_param.c_cflag &= ~PARODD;
167 tty_param.c_cc[VMIN] = 0;
168 tty_param.c_cc[VTIME] = 15;
169 cfsetospeed(&tty_param, B9600);
170 cfsetispeed(&tty_param, B9600);
171
172 tcgetattr(com_hdl, &old_tty);
173
174 if (tcsetattr(com_hdl, TCSANOW, &tty_param) == -1)
175 {
176 perror("tcsetattr");
177 fprintf(stderr, "Could not init %s for camera access.\n", com_dev);
178 close(com_hdl);
179 exit(-1);
180 }
181
182 set_com_baud(baud);
183
184 }
185
close_com(void)186 void close_com(void)
187 {
188 tcsetattr(com_hdl, TCSANOW, &old_tty);
189 close(com_hdl);
190 }
191 /* end of hardware specific functions *******************************/
192
193
194 /* GLOBAL FUNCTIONS ****************************************/
195
send_cmd(unsigned char * cmd)196 int send_cmd(unsigned char *cmd)
197 {
198 int i, error= 0;
199
200 pause(100);
201
202 for (i=1; i<=cmd[0]; i++)
203 {
204 cxmit(cmd[i]);
205 }
206
207 if (crcv(&error) != 0xD1)
208 if (dc_type == 0x20)
209 error+= ERR_DATA_WRONG;
210
211 return error;
212 }
213
init_dc20(int com_nr,long baud)214 int init_dc20(int com_nr, long baud)
215 {
216 int wait= 3;
217 int error=0;
218
219 initcom(com_nr, 9600);
220
221 while ( (error=(send_cmd(cmd_init)))!=0 && --wait) ;
222
223 if (error)
224 return error;
225
226 switch (baud)
227 {
228 case 19200: cmd_init[3]= 0x19; cmd_init[4]= 0x20; break;
229 case 38400: cmd_init[3]= 0x38; cmd_init[4]= 0x40; break;
230 case 57600: cmd_init[3]= 0x57; cmd_init[4]= 0x60; break;
231 case 115200: cmd_init[3]= 0x11; cmd_init[4]= 0x52; break;
232 default: cmd_init[3]= 0x96; cmd_init[4]= 0x00; baud= 9600;
233 }
234
235 wait= 3;
236 while ( (error=(send_cmd(cmd_init)))!=0 && --wait) ;
237 if (error)
238 return error;
239
240 set_com_baud(baud);
241
242 wait= 3;
243 while ( (error=(send_cmd(cmd_init)))!=0 && --wait) ;
244
245 return error;
246 }
247
248
close_dc20(void)249 void close_dc20(void)
250 {
251 /* reset to 9600Baud */
252 cmd_init[3]= 0x96;
253 cmd_init[4]= 0x00;
254 send_cmd(cmd_init);
255
256 set_com_baud(9600L);
257 close_com();
258 }
259
get_status(void)260 int get_status(void)
261 {
262 int wait= 10;
263 int error=0, dmy;
264
265 while ( (error=(send_cmd(cmd_init)))!=0 && --wait) ;
266
267 if (error)
268 return error;
269
270 wait= 10;
271 while ( (error=(send_cmd(cmd_status)))!=0 && --wait) ;
272 if (error)
273 return error;
274
275 if (read_from_com( 257) != 257)
276 {
277 return ERR_PACKET_WRONG;
278 }
279
280 cxmit(0xD2);
281
282 crcv(&error);
283
284 dc_type= inp_buff[1];
285 if (dc_type == 0x20)
286 {
287 sts_res= inp_buff[23];
288 sts_bat= inp_buff[29];
289 sts_pic_cnt= inp_buff[9];
290 sts_pic_rem= inp_buff[11];
291 }
292 else
293 {
294 sts_res= inp_buff[11];
295 sts_bat= inp_buff[29];
296 sts_pic_cnt= inp_buff[17] + inp_buff[19];
297 if (sts_res == RES_HIGH)
298 sts_pic_rem= inp_buff[21];
299 else
300 sts_pic_rem= inp_buff[23];
301 }
302
303 return error;
304 }
305
take_picture(void)306 int take_picture(void)
307 {
308 unsigned char rcv;
309 unsigned wait= 3;
310 int error= 0;
311
312 if ((error= get_status())!=0)
313 return error;
314
315 if (sts_pic_rem==0)
316 return ERR_IMPOSSIBLE;
317
318 send_cmd(cmd_shot);
319
320 for (;;)
321 {
322 rcv=crcv(&error);
323 if (error)
324 break;
325 }
326
327 /* now photo is taken */
328
329 wait= 10;
330 error= 0;
331 while ( ((rcv=crcv(&error)) != 0) && wait-- )
332 error= 0;
333
334 if ( (rcv != 0) || error )
335 {
336 return ERR_NO_RESPONSE;
337 }
338
339 /* camera is ready again */
340
341 error= get_status();
342
343 return error;
344 }
345
erase_dc20_memory(void)346 int erase_dc20_memory(void)
347 {
348 char rcv;
349 unsigned wait= 30;
350 int error= 0;
351
352 if ((error= get_status())!=0)
353 return error;
354
355 if (sts_pic_cnt==0)
356 return ERR_IMPOSSIBLE;
357
358 if ((error= send_cmd(cmd_erase))!=0)
359 return error;
360
361 while ( ((rcv=crcv(&error)) != 0) && wait-- )
362 error= 0;
363
364 if ( (rcv != 0) || error )
365 {
366 return ERR_NO_RESPONSE;
367 }
368
369 if ((error= get_status())!=0)
370 return error;
371
372 return error;
373 }
374
toggle_resolution(void)375 int toggle_resolution(void)
376 {
377 int error= 0;
378
379 if ((error= get_status())!=0)
380 return error;
381
382 if (dc_type == 0x25)
383 return ERR_NO_DC25_SUPP;
384
385 if (sts_pic_cnt)
386 return ERR_IMPOSSIBLE;
387
388 if (sts_res == RES_LOW)
389 {
390 if ((error= send_cmd(cmd_hires))!=0)
391 return error;
392 }
393 else
394 {
395 if ((error= send_cmd(cmd_lores))!=0)
396 return error;
397 }
398
399 error= 0;
400 for (;;)
401 {
402 crcv(&error);
403 if (error)
404 break;
405 }
406
407 if ((error= get_status())!=0)
408 return error;
409
410 return error;
411 }
412
load_thumbnails(FILE * ofp)413 int load_thumbnails(FILE *ofp)
414 {
415 int i, blk, error= 0;
416
417 if ((error= get_status())!=0)
418 return error;
419
420 if (dc_type == 0x25)
421 return ERR_NO_DC25_SUPP;
422
423 if (sts_pic_cnt==0)
424 return ERR_IMPOSSIBLE;
425
426 for (i=1; i<= sts_pic_cnt; i++)
427 {
428 cmd_thumbn[4]= (char) i;
429
430 if ((error= send_cmd(cmd_thumbn))!=0)
431 return error;
432
433 for (blk= 0; blk< 5; blk++)
434 {
435 if (read_from_com( Kb+1) != Kb+1)
436 return ERR_PACKET_WRONG;
437
438 if (fwrite(inp_buff, 1, Kb, ofp) != Kb)
439 return ERR_DATA_SAVE;
440
441 if (blk%2 == 0)
442 {
443 printf(".");
444 fflush(stdout);
445 }
446
447 cxmit(0xD2);
448 }
449 crcv(&error);
450 }
451
452 return error;
453 }
454
download_picture(int pic_no,FILE * ofp)455 int download_picture(int pic_no, FILE *ofp)
456 {
457 int blk, max_blk, error= 0;
458
459 if ((error= get_status())!=0)
460 return error;
461
462 if (sts_pic_cnt < pic_no)
463 return ERR_IMPOSSIBLE;
464
465 cmd_ldpic2[4]= (char) pic_no;
466
467 if ((error= send_cmd(cmd_ldpic2))!=0)
468 return error;
469
470 if (read_from_com( Kb+1) != Kb+1)
471 return ERR_PACKET_WRONG;
472
473 if (fwrite(inp_buff, 1, Kb, ofp) != Kb)
474 return ERR_DATA_SAVE;
475
476 cxmit(0xD2);
477
478 if (inp_buff[4] == RES_HIGH)
479 max_blk= 122;
480 else
481 max_blk= 61;
482
483 for (blk= 1; blk< max_blk; blk++)
484 {
485 if (read_from_com( Kb+1) != Kb+1)
486 return ERR_PACKET_WRONG;
487
488 if (fwrite(inp_buff, 1, Kb, ofp) != Kb)
489 return ERR_DATA_SAVE;
490
491 if (blk%2 == 0)
492 {
493 printf(".");
494 fflush(stdout);
495 }
496
497 cxmit(0xD2);
498 }
499
500 crcv(&error);
501
502 return error;
503 }
504
505
load_image_infos(int img_inf[MAX_PICT][5])506 int load_image_infos(int img_inf[MAX_PICT][5])
507 {
508 int i, error= 0;
509
510 if ((error= get_status())!=0)
511 return error;
512
513 for (i=1; i<= sts_pic_cnt; i++)
514 {
515 if (i > MAX_PICT)
516 break;
517
518 cmd_ldpic1[4]= (char) i;
519
520 if ((error= send_cmd(cmd_ldpic1))!=0)
521 return error;
522
523 if (read_from_com( 257) != 257)
524 return ERR_PACKET_WRONG;
525
526 img_inf[i][0]= inp_buff[16];
527 img_inf[i][1]= inp_buff[17];
528 img_inf[i][2]= inp_buff[34];
529 img_inf[i][3]= inp_buff[35];
530 img_inf[i][4]= inp_buff[4];
531
532 cxmit(0xD2);
533
534 crcv(&error);
535 }
536
537 return error;
538 }
539