Logo Search packages:      
Sourcecode: libgphoto2 version File versions

usb.c

/*
 * 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;
}

Generated by  Doxygen 1.6.0   Back to index