3 * Copyright © 2001 Lutz Müller
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
21 #include "casio-qv-commands.h"
35 #define CASIO_QV_RETRIES 5
37 #define CR(result) {int r = (result); if (r < 0) return (r);}
40 QVping (Camera *camera)
43 int result = GP_OK, i = 0;
45 /* Send ENQ and wait for ACK */
48 CR (gp_port_write (camera->port, &c, 1));
49 result = gp_port_read (camera->port, &c, 1);
51 /* If we got ACK, everything is fine. */
58 * According to gphoto, we need to wait
59 * for ACK. But the camera of
60 * David Wolfskill <david@catwhisker.org>
61 * seems to return ENQ after some NAK.
67 /* The camera is not yet ready. */
74 * David Wolfskill <david@catwhisker.org>
75 * has seen those two bytes if one sends
76 * only ENQs to the camera. The camera first
77 * answers with some NAKs, then with some
78 * ACKs, and finally with UNKNOWN1 and
81 while (gp_port_read (camera->port, &c, 1) >= 0);
85 while (gp_port_read (camera->port, &c, 1) >= 0);
90 if (++i < CASIO_QV_RETRIES)
93 /* If we got an error from libgphoto2_port, pass it along */
96 /* Return some error code */
97 return (GP_ERROR_CORRUPTED_DATA);
102 QVsend (Camera *camera, unsigned char *cmd, int cmd_len,
103 unsigned char *buf, int buf_len)
107 const unsigned char *cmd_end;
109 /* The camera does not insist on a ping each command, but */
110 /* sometimes it hangs up without one. */
111 CR (QVping (camera));
113 /* Write the request and calculate the checksum */
114 CR (gp_port_write (camera->port, cmd, cmd_len));
115 for (cmd_end = cmd+cmd_len, checksum = 0; cmd < cmd_end; ++cmd)
118 /* Read the checksum */
119 CR (gp_port_read (camera->port, &c, 1));
120 if (c != (unsigned char)(~checksum))
121 return (GP_ERROR_CORRUPTED_DATA);
125 CR (gp_port_write (camera->port, &c, 1));
127 /* Receive the answer */
129 CR (gp_port_read (camera->port, buf, buf_len));
135 QVblockrecv (Camera *camera, unsigned char **buf, unsigned long int *buf_len)
137 /* XXX - does the caller know to free *buf in case of an error? */
148 CR (gp_port_write (camera->port, &c, 1));
151 unsigned char buffer[2];
157 CR (gp_port_read (camera->port, &c, 1));
161 CR (gp_port_write (camera->port, &c, 1));
162 if (retries > CASIO_QV_RETRIES)
163 return (GP_ERROR_CORRUPTED_DATA);
168 /* Read sector size */
169 CR (gp_port_read (camera->port, buffer, 2));
170 size = (buffer[0] << 8) | buffer[1];
171 sum = buffer[0] + buffer[1];
173 /* Allocate the memory */
174 new = (unsigned char*)realloc (*buf, sizeof (char) * (*buf_len + size));
175 if (new == (unsigned char*)0) {
176 if (*buf != (unsigned char*)0) free(*buf);
177 return (GP_ERROR_NO_MEMORY);
183 CR (gp_port_read (camera->port, *buf + pos, size));
184 for (i = 0; i < size; i++)
185 sum += (*buf)[i + pos];
187 /* Get EOT or ETX and the checksum */
188 CR (gp_port_read (camera->port, buffer, 2));
191 /* Verify the checksum */
192 if ((unsigned char)(~sum) != buffer[1]) {
195 CR (gp_port_write (camera->port, &c, 1));
196 if (retries > CASIO_QV_RETRIES)
197 return (GP_ERROR_CORRUPTED_DATA);
202 /* Acknowledge and prepare for next packet */
204 CR (gp_port_write (camera->port, &c, 1));
208 if (buffer[0] == ETX)
210 else if (buffer[0] == ETB)
213 return (GP_ERROR_CORRUPTED_DATA);
220 QVbattery (Camera *camera, float *battery)
222 unsigned char cmd[6];
231 CR (QVsend (camera, cmd, 6, &b, 1));
238 QVrevision (Camera *camera, long int *revision)
240 unsigned char cmd[2];
241 unsigned char buf[4];
245 CR (QVsend (camera, cmd, 2, buf, 4));
246 *revision = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
252 QVnumpic (Camera *camera)
254 unsigned char cmd[2];
259 CR (QVsend (camera, cmd, 2, &b, 1));
265 QVpicattr (Camera *camera, int n, unsigned char *picattr)
267 unsigned char cmd[4];
274 CR (QVsend (camera, cmd, 4, &b, 1));
281 QVshowpic (Camera *camera, int n)
283 unsigned char cmd[3];
288 CR (QVsend (camera, cmd, 3, NULL, 0));
294 QVsetpic (Camera *camera)
296 unsigned char cmd[2];
300 CR (QVsend (camera, cmd, 2, NULL, 0));
306 QVgetCAMpic (Camera *camera, unsigned char **data, unsigned long int *size, int fine)
308 unsigned char cmd[2];
311 cmd[1] = fine ? 'g' : 'G';
312 CR (QVsend (camera, cmd, 2, NULL, 0));
313 CR (QVblockrecv (camera, data, size));
319 QVgetYCCpic (Camera *camera, unsigned char **data, unsigned long int *size)
321 unsigned char cmd[2];
325 CR (QVsend (camera, cmd, 2, NULL, 0));
326 CR (QVblockrecv (camera, data, size));
332 QVdelete (Camera *camera, int n)
334 unsigned char cmd[4];
340 CR (QVsend (camera, cmd, 4, NULL, 0));
346 QVprotect (Camera *camera, int n, int on)
348 unsigned char cmd[4];
354 CR (QVsend (camera, cmd, 4, NULL, 0));
360 QVsize (Camera *camera, long int *size)
362 unsigned char cmd[2];
363 unsigned char buf[4];
367 CR (QVsend (camera, cmd, 2, buf, 4));
368 *size = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
374 QVcapture (Camera *camera)
376 unsigned char cmd[2];
381 CR (QVsend (camera, cmd, 2, &b, 1));
387 QVstatus (Camera *camera, char *status)
389 unsigned char cmd[3];
394 CR (QVsend (camera, cmd, 3, status, 2));
400 QVreset (Camera *camera)
402 unsigned char cmd[2];
406 CR (QVsend (camera, cmd, 2, NULL, 0));
412 QVsetspeed (Camera *camera, int speed)
414 unsigned char cmd[3];
415 gp_port_settings settings;
420 case 9600: cmd[2] = 46; break;
421 case 19200: cmd[2] = 22; break;
422 case 38400: cmd[2] = 11; break;
423 case 57600: cmd[2] = 7; break;
424 case 115200: cmd[2] = 3; break;
425 default: return (GP_ERROR_NOT_SUPPORTED);
427 CR (QVsend (camera, cmd, 3, NULL, 0));
429 CR (gp_port_get_settings (camera->port, &settings));
430 settings.serial.speed = speed;
431 CR (gp_port_set_settings (camera->port, settings));
433 CR (QVping (camera));