Example #1
0
/* this functions reads button status */
static SANE_Status
rts8891_read_buttons (SANE_Int devnum, SANE_Int * mask)
{
  SANE_Status status = SANE_STATUS_GOOD;
  SANE_Byte reg;

  /* check CONTROL_REG */
  sanei_rts88xx_read_reg (devnum, CONTROL_REG, &reg);

  /* read 'base' button status */
  sanei_rts88xx_read_reg (devnum, 0x25, &reg);
  DBG (DBG_io, "rts8891_read_buttons: r25=0x%02x\n", reg);
  *mask |= reg;

  /* read 'extended' button status */
  sanei_rts88xx_read_reg (devnum, 0x1a, &reg);
  DBG (DBG_io, "rts8891_read_buttons: r1a=0x%02x\n", reg);
  *mask |= reg << 8;

  /* clear register r25 */
  reg = 0x00;
  sanei_rts88xx_write_reg (devnum, 0x25, &reg);

  /* clear register r1a */
  sanei_rts88xx_read_reg (devnum, 0x1a, &reg);
  reg = 0x00;
  status = sanei_rts88xx_write_reg (devnum, 0x1a, &reg);

  DBG (DBG_info, "rts8891_read_buttons: mask=0x%04x\n", *mask);
  return status;
}
Example #2
0
/*
 * setup nvram
 */
SANE_Status
sanei_rts88xx_setup_nvram (SANE_Int devnum, SANE_Int length,
                           SANE_Byte * value)
{
  SANE_Status status = SANE_STATUS_GOOD;
  SANE_Byte local[2], reg;
  int i;

  status = sanei_rts88xx_nvram_ctrl (devnum, length, value);

#ifndef HAZARDOUS_EXPERIMENT
  return SANE_STATUS_GOOD;
#endif
  if (status != SANE_STATUS_GOOD)
    {
      DBG (DBG_error, "sanei_rts88xx_setup_nvram : failed step #1 ...\n");
      return status;
    }
  local[0] = 0x18;
  local[1] = 0x08;
  for (i = 0; i < 8; i++)
    {
      status = sanei_rts88xx_nvram_ctrl (devnum, 2, local);
      if (status != SANE_STATUS_GOOD)
        {
          DBG (DBG_error, "sanei_rts88xx_setup_nvram : failed loop #%d ...\n",
               i);
          return status;
        }
      status = sanei_rts88xx_read_reg (devnum, 0x10, &reg);
      if (status != SANE_STATUS_GOOD)
        {
          DBG (DBG_error,
               "sanei_rts88xx_setup_nvram : register reading failed loop #%d ...\n",
               i);
          return status;
        }
      DBG (DBG_io, "sanei_rts88xx_setup_nvram: reg[0x10]=0x%02x\n", reg);
    }
  reg = 0;
  status = sanei_rts88xx_write_reg (devnum, CONTROLER_REG, &reg);
  if (status != SANE_STATUS_GOOD)
    {
      DBG (DBG_error,
           "sanei_rts88xx_setup_nvram : controler register write failed\n");
      return status;
    }
  reg = 1;
  status = sanei_rts88xx_write_reg (devnum, CONTROLER_REG, &reg);
  if (status != SANE_STATUS_GOOD)
    {
      DBG (DBG_error,
           "sanei_rts88xx_setup_nvram : controler register write failed\n");
      return status;
    }
  return status;
}
Example #3
0
/*
 * write to special control register CONTROL_REG=0xb3 
 */
SANE_Status
sanei_rts88xx_write_control (SANE_Int devnum, SANE_Byte value)
{
  SANE_Status status;
  status = sanei_rts88xx_write_reg (devnum, CONTROL_REG, &value);
  return status;
}
Example #4
0
 /**
  * wait for the scanning head to reach home position
  */
static SANE_Status
rts8891_wait_for_home (struct Rts8891_Device *device, SANE_Byte * regs)
{
  SANE_Status status = SANE_STATUS_GOOD;
  SANE_Byte motor, sensor, reg;

  DBG (DBG_proc, "rts8891_wait_for_home: start\n");

  /* wait for controller home bit to raise, no timeout */
  /* at each loop we check that motor is on, then that the sensor bit it cleared */
  do
    {
      sanei_rts88xx_read_reg (device->devnum, CONTROL_REG, &motor);
      sanei_rts88xx_read_reg (device->devnum, CONTROLER_REG, &sensor);
    }
  while ((motor & 0x08) && ((sensor & 0x02) == 0));

  /* flag that device has finished parking */
  device->parking=SANE_FALSE;

  /* check for error */
  if (((motor & 0x08) == 0x00) && ((sensor & 0x02) == 0))
    {
      DBG (DBG_error,
	   "rts8891_wait_for_home: error, motor stopped before head parked\n");
      status = SANE_STATUS_INVAL;
    }

  /* re-enable CCD */
  regs[0] = regs[0] & 0xef;

  sanei_rts88xx_cancel (device->devnum);

  /* reset ? so we don't need to read data */
  reg = 0;
  /* b7: movement on/off, b3-b0 : movement divisor */
  sanei_rts88xx_write_reg (device->devnum, 0x33, &reg);
  sanei_rts88xx_write_reg (device->devnum, 0x33, &reg);
  /* movement direction */
  sanei_rts88xx_write_reg (device->devnum, 0x36, &reg);
  sanei_rts88xx_cancel (device->devnum);

  DBG (DBG_proc, "rts8891_wait_for_home: end\n");
  return status;
}
Example #5
0
/* this functions "commits" pending scan command */
static SANE_Status
rts8891_commit (SANE_Int devnum, SANE_Byte value)
{
  SANE_Status status;
  SANE_Byte reg;

  reg = value;
  sanei_rts88xx_write_reg (devnum, 0xd3, &reg);
  sanei_rts88xx_cancel (devnum);
  sanei_rts88xx_write_control (devnum, 0x08);
  status = sanei_rts88xx_write_control (devnum, 0x08);
  return status;
}
Example #6
0
/* reads data from scanner.
 * First we wait for some data to be available and then loop reading
 * from scanner until the required amount is reached.
 * We handle non blocking I/O by returning immediatly (with SANE_STATUS_BUSY)
 * if there is no data available from scanner. But once read is started,
 * all the required amount is read. Once wait for data succeeded, we still poll
 * for data in order no to read it too fast, but we don' take care of non blocking
 * mode since we cope with it on first data wait.
 */
static SANE_Status
read_data (struct Rts8891_Session *session, SANE_Byte * dest, SANE_Int length)
{
  SANE_Status status = SANE_STATUS_GOOD;
  SANE_Int count, read, len, dummy;
  struct Rts8891_Device *dev = session->dev;
  static FILE *raw = NULL;	/* for debugging purpose we need it static */
  SANE_Byte control = 0x08;
  unsigned char buffer[RTS88XX_MAX_XFER_SIZE];

  DBG (DBG_proc, "read_data: start\n");
  DBG (DBG_proc, "read_data: requiring %d bytes\n", length);

  /* wait for data being available and handle non blocking mode */
  /* only when data reading hasn't produce any data yet */
  if (dev->read == 0)
    {
      do
	{
	  status = sanei_rts88xx_data_count (dev->devnum, &count);
	  if (status != SANE_STATUS_GOOD)
	    {
	      DBG (DBG_error, "read_data: failed to wait for data\n");
	      return status;
	    }
	  if (count == 0)
	    {
	      sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &control);
	      if ((control & 0x08) == 0 && (count == 0))
		{
		  DBG (DBG_error,
		       "read_data: scanner stopped being busy before data are available\n");
		  return SANE_STATUS_IO_ERROR;
		}
	    }

	  /* in case there is no data, we return BUSY since this mean    */
	  /* that scanning head hasn't reach is position and data hasn't */
	  /* come yet */
	  if (session->non_blocking && count == 0)
	    {

	      dev->regs[LAMP_REG] = 0x8d;
	      sanei_rts88xx_write_reg (dev->devnum, LAMP_REG,
				       &(dev->regs[LAMP_REG]));
	      DBG (DBG_io, "read_data: no data vailable\n");
	      DBG (DBG_proc, "read_data: end\n");
	      return SANE_STATUS_DEVICE_BUSY;
	    }
	}
      while (count == 0);
    }
  else
    {				/* start of read for a new block */
      status = sanei_rts88xx_data_count (dev->devnum, &count);
      if (status != SANE_STATUS_GOOD)
	{
	  DBG (DBG_error, "read_data: failed to wait for data\n");
	  return status;
	}
      if (count == 0)
	{
	  sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &control);
	  if ((control & 0x08) == 0 && (count == 0))
	    {
	      DBG (DBG_error,
		   "read_data: scanner stopped being busy before data are available\n");
	      return SANE_STATUS_IO_ERROR;
	    }
	}
    }

  /* fill scanned data buffer */
  read = 0;

  /* now loop reading data until we have the amount requested */
  /* we also take care of not reading too much data           */
  while (read < length && dev->read < dev->to_read
	 && ((control & 0x08) == 0x08))
    {
      /* used to sync */
      if (dev->read == 0)
	{
	  status = sanei_rts88xx_data_count (dev->devnum, &dummy);
	  if (status != SANE_STATUS_GOOD)
	    {
	      DBG (DBG_error, "read_data: failed to read data count\n");
	      return status;
	    }
	}

      /* if there is data to read, read it */
      if (count > 0)
	{
	  len = count;

	  if (len > RTS88XX_MAX_XFER_SIZE)
	    {
	      len = RTS88XX_MAX_XFER_SIZE;
	    }

	  /* we only read even size blocks of data */
	  if (len & 1)
	    {
	      DBG (DBG_io, "read_data: round to next even number\n");
	      len++;
	    }

	  if (len > length - read)
	    {
	      len = length - read;
	    }

	  status = sanei_rts88xx_read_data (dev->devnum, &len, dest + read);
	  if (status != SANE_STATUS_GOOD)
	    {
	      DBG (DBG_error, "read_data: failed to read from scanner\n");
	      return status;
	    }

	  /* raw data tracing */
	  if (DBG_LEVEL >= DBG_io2)
	    {
	      /* open a new file only when no data scanned */
	      if (dev->read == 0)
		{
		  raw = fopen ("raw_data.pnm", "wb");
		  if (raw != NULL)
		    {
		      /* PNM header */
		      fprintf (raw, "P%c\n%d %d\n255\n",
			       session->params.format ==
			       SANE_FRAME_RGB
			       || session->emulated_gray ==
			       SANE_TRUE ? '6' : '5', dev->pixels,
			       dev->lines);
		    }
		}
	      if (raw != NULL)
		{
		  fwrite (dest + read, 1, len, raw);
		}
	    }

	  /* move pointer and counter */
	  read += len;
	  dev->read += len;
	  DBG (DBG_io2, "read_data: %d/%d\n", dev->read, dev->to_read);
	}

      /* in fast scan mode, read data count
       * in slow scan, head moves by the amount of data read */
      status = sanei_rts88xx_data_count (dev->devnum, &count);
      if (status != SANE_STATUS_GOOD)
	{
	  DBG (DBG_error, "read_data: failed to read data count\n");
	  return status;
	}

      /* if no data, check if still scanning */
      if (count == 0 && dev->read < dev->to_read)
	{
	  sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &control);
	  if ((control & 0x08) == 0x00)
	    {
	      DBG (DBG_error,
		   "read_data: scanner stopped being busy before data are available\n");
	      return SANE_STATUS_IO_ERROR;
	    }
	}
    }

  /* end of physical reads */
  if (dev->read >= dev->to_read)
    {
      /* check there is no more data in case of a bug */
      sanei_rts88xx_data_count (dev->devnum, &count);
      if (count > 0)
	{
	  DBG (DBG_warn,
	       "read_data: %d bytes are still available from scanner\n",
	       count);

	  /* flush left-over data */
	  while (count > 0)
	    {
	      len = count;
	      if (len > RTS88XX_MAX_XFER_SIZE)
		{
		  len = RTS88XX_MAX_XFER_SIZE;
		}

	      /* we only read even size blocks of data */
	      if (len & 1)
		{
		  len++;
		}
	      sanei_rts88xx_read_data (dev->devnum, &len, buffer);
	      sanei_rts88xx_data_count (dev->devnum, &count);
	    }
	}

      /* wait for motor to stop at the end of the scan */
      do
	{
	  sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &control);
	}
      while ((control & 0x08) != 0);

      /* close log file if needed */
      if (DBG_LEVEL >= DBG_io2)
	{
	  if (raw != NULL)
	    {
	      fclose (raw);
	      raw = NULL;
	    }
	}
    }

  DBG (DBG_io, "read_data: read %d bytes from scanner\n", length);
  DBG (DBG_proc, "read_data: end\n");
  return status;
}
Example #7
0
/* resets lamp */
SANE_Status
sanei_rts88xx_reset_lamp (SANE_Int devnum, SANE_Byte * regs)
{
  SANE_Status status;
  SANE_Byte reg;

  /* read the 0xda register, then clear lower nibble and write it back */
  status = sanei_rts88xx_read_reg (devnum, 0xda, &reg);
  if (status != SANE_STATUS_GOOD)
    {
      DBG (DBG_error,
           "sanei_rts88xx_reset_lamp: failed to read 0xda register\n");
      return status;
    }
  reg = 0xa0;
  status = sanei_rts88xx_write_reg (devnum, 0xda, &reg);
  if (status != SANE_STATUS_GOOD)
    {
      DBG (DBG_error,
           "sanei_rts88xx_reset_lamp: failed to write 0xda register\n");
      return status;
    }

  /* on cleared, get status */
  status = sanei_rts88xx_get_status (devnum, regs);
  if (status != SANE_STATUS_GOOD)
    {
      DBG (DBG_error, "sanei_rts88xx_reset_lamp: failed to get status\n");
      return status;
    }
  DBG (DBG_io, "sanei_rts88xx_reset_lamp: status=0x%02x 0x%02x\n", regs[0x10],
       regs[0x11]);

  /* set low nibble to 7 and write it */
  reg = reg | 0x07;
  status = sanei_rts88xx_write_reg (devnum, 0xda, &reg);
  if (status != SANE_STATUS_GOOD)
    {
      DBG (DBG_error,
           "sanei_rts88xx_reset_lamp: failed to write 0xda register\n");
      return status;
    }
  status = sanei_rts88xx_read_reg (devnum, 0xda, &reg);
  if (status != SANE_STATUS_GOOD)
    {
      DBG (DBG_error,
           "sanei_rts88xx_reset_lamp: failed to read 0xda register\n");
      return status;
    }
  if (reg != 0xa7)
    {
      DBG (DBG_warn,
           "sanei_rts88xx_reset_lamp: expected reg[0xda]=0xa7, got 0x%02x\n",
           reg);
    }
  
  /* store read value in shadow register */
  regs[0xda] = reg;

  return status;
}