Logo Search packages:      
Sourcecode: libgphoto2 version File versions

rs232.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.
 */

#include <gphoto2/gphoto2-library.h>
#include <gphoto2/gphoto2-result.h>

#include "print.h"
#include "rs232.h"
#include "mdc800_spec.h"
#include "io.h"

#include <fcntl.h>
#include <termios.h>
#include <sys/time.h>


/*
 * sends a command and receives the answer to this
 * buffer: Strores the answer
 * length: length of answer or null
 */
int mdc800_rs232_sendCommand(GPPort *port,char* command, char* buffer, int length)
{
      char answer;
      int fault=0,ret;
      int i;

      printFnkCall ("(mdc800_rs232_sendCommand) id:%i (%i,%i,%i),answer:%i\n",command[1],command[2],command[3],command[4],length);

      usleep(MDC800_DEFAULT_COMMAND_DELAY*1000);
      gp_port_set_timeout (port, MDC800_DEFAULT_TIMEOUT );

      /* Send command */
      for (i=0; i<6; i++)
      {
            if (gp_port_write (port, &command[i] ,1) < GP_OK)
            {
                  printCError ("(mdc800_rs232_sendCommand) sending Byte %i fails!\n",i);
                  fault=1;
            }

            ret = gp_port_read (port,&answer,1);
            if ( ret != 1)
            {
                  printCError ("(mdc800_rs232_sendCommand) receiving resend of Byte %i fails.\n",i);
                  fault=1;
            }
            if (command [i] != answer)
            {
                  printCError ("(mdc800_rs232_sendCommand) Byte %i differs : send %i, received %i \n",i,command[i],answer);
                  fault=1;
            }
      }
      if (fault)
            return GP_ERROR_IO;

      /* Receive answer */
      if (length)
      {
            /* Some Commands needs a download. */
            switch (command[1])
            {
                  case COMMAND_GET_IMAGE:
                  case COMMAND_GET_THUMBNAIL:
                        if (!mdc800_rs232_download(port,buffer,length))
                        {
                              printCError ("(mdc800_rs232_sendCommand) download of %i Bytes fails.\n",length);
                              fault=1;
                        }
                        break;
                  default:
                        if (!mdc800_rs232_receive(port,buffer,length))
                        {
                              printCError ("(mdc800_rs232_sendCommand) receiving %i Bytes fails.\n",length);
                              fault=1;
                        }
            }
      }

      if (fault)
            return GP_ERROR_IO;

      /* commit */
      if (!(command[1] == COMMAND_CHANGE_RS232_BAUD_RATE)) {
            if (!mdc800_rs232_waitForCommit(port,command[1]))
            {
                  printCError ("(mdc800_rs232_sendCommand) receiving commit fails.\n");
                  fault=1;
            }
      }
      if (fault)
            return GP_ERROR_IO;
      return GP_OK;
}


/*
 * waits for the Commit value
 * The function expexts the commandid auf the corresponding command
 * to determiante, wether a long timeout is needed or not. (Take Photo)
 */
int mdc800_rs232_waitForCommit (GPPort *port,char commandid)
{
      char ch[1];
      int ret;

      gp_port_set_timeout(port,mdc800_io_getCommandTimeout(commandid));
      ret = gp_port_read(port,ch,1);
      if (ret!=1)
      {
            printCError ("(mdc800_rs232_waitForCommit) Error receiving commit !\n");
            return GP_ERROR_IO;
      }

      if (ch[0] != ANSWER_COMMIT )
      {
            printCError ("(mdc800_rs232_waitForCommit) Byte \"%i\" was not the commit !\n",ch[0]);
            return GP_ERROR_IO;
      }
      return GP_OK;
}

/*
 * receive Bytes from camera
 */
int mdc800_rs232_receive (GPPort *port,char* buffer, int b)
{
      int ret;
      gp_port_set_timeout (port,MDC800_DEFAULT_TIMEOUT );

      ret=gp_port_read(port,buffer,b);
      if (ret!=b)
      {
            printCError ("(mdc800_rs232_receive) can't read %i Bytes !\n",b);
            return GP_ERROR_IO;
      }
      return GP_OK;
}


/*
 * downloads data from camera and send
 * a checksum every 512 bytes.
 */
int mdc800_rs232_download (GPPort *port,char* buffer, int size)
{
      int checksum,readen=0,i;
      char DSC_checksum;
      int numtries=0;

      gp_port_set_timeout(port, MDC800_DEFAULT_TIMEOUT );

      while (readen < size)
      {
            if (!mdc800_rs232_receive (port,&buffer[readen],512))
                  return readen;
            checksum=0;
            for (i=0; i<512; i++)
                  checksum=(checksum+(unsigned char) buffer [readen+i])%256;
            if (gp_port_write (port,(char*) &checksum,1) < GP_OK)
                  return readen;

            if (!mdc800_rs232_receive (port,&DSC_checksum,1))
                  return readen;


            if ((char) checksum != DSC_checksum)
            {
                  numtries++;
                  printCError ("(mdc800_rs232_download) checksum: software %i, DSC %i , reload block! (%i) \n",checksum,(unsigned char)DSC_checksum,numtries);
                  if (numtries > 10)
                  {
                        printCError ("(mdc800_rs232_download) to many retries, giving up..");
                        return 0;
                  }
            }
            else
            {
                  readen+=512;
                  numtries=0;
            }
      }


      {
            int i,j;
            unsigned char* b=(unsigned char*) buffer;
            for (i=0; i<4; i++)
            {
                  printCError ("%i: ",i);
                  for (j=0; j<8; j++)
                        printCError (" %i", b[i*8+j]);
                  printCError ("\n");
            }
      }
      return readen;
}

Generated by  Doxygen 1.6.0   Back to index