summaryrefslogtreecommitdiff
path: root/camlibs/mustek/usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'camlibs/mustek/usb.c')
-rw-r--r--camlibs/mustek/usb.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/camlibs/mustek/usb.c b/camlibs/mustek/usb.c
new file mode 100644
index 000000000..44fb2d657
--- /dev/null
+++ b/camlibs/mustek/usb.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright © 1999/2000 by Henning Zabel <henning@uni-paderborn.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * gphoto driver for the Mustek MDC800 Digital Camera. The driver
+ * supports rs232 and USB.
+ */
+
+/*
+ Implemenation of the USB Version of ExecuteCommand
+*/
+#include <string.h>
+
+#include <gphoto2/gphoto2-library.h>
+#include <gphoto2/gphoto2-result.h>
+
+#include "print.h"
+#include "usb.h"
+#include "io.h"
+#include "mdc800_spec.h"
+
+#include <fcntl.h>
+#include <sys/time.h>
+
+
+/*
+ * Checks wether the camera responds busy
+ */
+static int mdc800_usb_isBusy (char* ch)
+{
+ int i;
+ for (i=0;i<8;i++)
+ if (ch [i] != (char)0x99)
+ return 0;
+ return 1;
+}
+
+
+/*
+ * Checks wether the Camera is ready
+ */
+static int mdc800_usb_isReady (char *ch)
+{
+ int i;
+ for (i=0;i<8;i++)
+ if (ch [i] != (char)0xbb)
+ return 0;
+ return 1;
+}
+
+
+/*
+ * Waits for the camera
+ * type: 0: Wait until the camera gets ready
+ * 1: Read data from irq
+ * The function stores the readen 8 Bytes in data.
+ * and return 0 on success else -1.
+ */
+static int mdc800_usb_readFromIrq (GPPort *port,int type,char* data,int timeout)
+{
+ int ret;
+ struct timeval tv;
+
+ gp_port_set_timeout(port,1);
+ timeout+=10*MDC800_USB_IRQ_INTERVAL;
+ gettimeofday(&tv,NULL);
+ while (timeout>=0)
+ {
+ /* try a read */
+ ret = gp_port_check_int(port,data,8);
+ if (ret!=8)
+ {
+ printCError ("(mdc800_usb_readFromIRQ) reading bytes from irq fails (%d)\n",ret);
+ return ret;
+ }
+ if (0) {
+ int i=0;
+ printf ("irq :");
+ for (i=0; i<8; i++)
+ {
+ printf ("%i ", (unsigned char)data [i]);
+ }
+ printf ("\n");
+ }
+ /* check data */
+ if (type)
+ {
+ if (!(mdc800_usb_isReady(data)||mdc800_usb_isBusy(data))) {
+ fprintf(stderr,"got data.\n");
+ /* Data received successfull */
+ return GP_OK;
+ }
+ } else {
+ if (mdc800_usb_isReady (data))
+ {
+ fprintf(stderr,"got readiness.\n");
+ /* Camera response ready */
+ return GP_OK;
+ }
+ }
+ /* wait the specified time */
+ if (0) {
+ struct timeval tv1,result;
+
+ gettimeofday(&tv1,NULL);
+ timersub(&tv1,&tv,&result);
+ if ((result.tv_sec > 0) || (result.tv_usec>=timeout*1000)) {
+ fprintf(stderr,"time out\n");
+ break;
+ }
+ }
+ if (1) {
+ struct timeval t;
+ t.tv_usec = MDC800_USB_IRQ_INTERVAL*1000;
+ t.tv_sec = 0;
+ select (1 , NULL, NULL, NULL, &t);
+ timeout-=MDC800_USB_IRQ_INTERVAL;
+ }
+ }
+ /* Timeout */
+ printCError ("(mdc800_usb_readFromIrq) timeout\n");
+ return GP_ERROR_IO;
+}
+
+int mdc800_usb_sendCommand(GPPort*port,char*command,char*buffer,int length)
+{
+ char tmp_buffer [16];
+ GPPortSettings settings;
+ int ret;
+
+ printf ("(mdc800_usb_sendCommand) id:%i (%i,%i,%i,%i,%i,%i),answer:%i\n",command[1],command[2],command[3],command[4],command[5],command[6],command[7],length);
+ /* Send the Command */
+ gp_port_set_timeout(port,MDC800_DEFAULT_TIMEOUT);
+
+ gp_port_get_settings(port,&settings);
+ settings.usb.outep = MDC800_USB_ENDPOINT_COMMAND;
+ gp_port_set_settings(port,settings);
+
+ ret = mdc800_usb_readFromIrq(port,0,tmp_buffer,MDC800_DEFAULT_TIMEOUT);
+ if (ret != GP_OK) {
+ fprintf(stderr,"Camera did not get ready before mdc800_usb_sendCommand!\n");
+ }
+
+ if ((ret=gp_port_write(port,command,8)) != 8)
+ {
+ printCError ("(mdc800_usb_sendCommand) sending Command fails (%d)!\n",ret);
+ return ret;
+ }
+
+ /* receive the answer */
+ switch ((unsigned char) command [1])
+ {
+ case COMMAND_GET_THUMBNAIL:
+ case COMMAND_GET_IMAGE:
+ gp_port_set_timeout (port, 2000);
+ if (gp_port_read (port,buffer,64) != 64)
+ {
+ printCError ("(mdc800_usb_sendCommand) requesting 64Byte dummy data fails.\n");
+ return GP_ERROR_IO;
+ }
+ fprintf(stderr,"got 64 byte\n");
+ { /* Download loop */
+ int readen=0;
+ while (readen < length)
+ {
+ if (gp_port_read(port,buffer+readen,64) != 64)
+ {
+ printCError ("(mdc800_usb_sendCommand) reading image data fails.\n");
+ return 0;
+ }
+ fprintf(stderr,"got 64 byte\n");
+ readen+=64;
+ }
+ }
+ break;
+ default :
+ if (length > 0)
+ {
+ int ret;
+ ret = mdc800_usb_readFromIrq (port,1,tmp_buffer, mdc800_io_getCommandTimeout(command[1]));
+ if (ret != GP_OK)
+ {
+ /* Reading fails */
+ printCError ("(mdc800_usb_sendCommand) receiving answer fails (%d).\n",ret);
+ return ret;
+ }
+ memcpy(buffer,tmp_buffer,length);
+ }
+ }
+#if 1
+ /* Waiting for camera to get ready */
+ ret = mdc800_usb_readFromIrq(port,0,tmp_buffer,mdc800_io_getCommandTimeout (command[1]));
+ if (ret!=GP_OK)
+ {
+ /* Reading fails */
+ printCError ("(mdc800_usb_sendCommand) camera didn't get ready in the defined intervall ?!\n");
+ return ret;
+ }
+#endif
+ return GP_OK;
+}