kopia lustrzana https://gitlab.com/sane-project/backends
* backend/canon_pp-dev.c backend/canon_pp-dev.h backend/canon_pp-io.c
backend/canon_pp-io.h backend/canon_pp.c backend/canon_pp.h: Fix init problem, add changes to facilitate configurable wakeup mode (for faster starts on FB360P and FB620P). * doc/sane-canon_pp.man doc/descriptions/canon_pp.desc: Updates regarding FB310P and FB610P (rebadged Avisions)DEVEL_2_0_BRANCH-1
rodzic
19694b6ce5
commit
51a3075282
|
@ -70,6 +70,7 @@
|
|||
/* No SANE, Things that only apply to stand-alone */
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
static void DBG(int level, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
@ -324,12 +325,12 @@ int sanei_canon_pp_init_scan(scanner_parameters *sp, scan_parameters *scanp)
|
|||
|
||||
|
||||
/* Wake the scanner, detect it, and fill sp with stuff */
|
||||
int sanei_canon_pp_initialise(scanner_parameters *sp)
|
||||
int sanei_canon_pp_initialise(scanner_parameters *sp, int mode)
|
||||
{
|
||||
unsigned char scanner_info[12];
|
||||
|
||||
/* Hopefully take the scanner out of transparent mode */
|
||||
if (sanei_canon_pp_wake_scanner(sp->port))
|
||||
if (sanei_canon_pp_wake_scanner(sp->port, mode))
|
||||
{
|
||||
DBG(10, "initialise: could not wake scanner\n");
|
||||
return 1;
|
||||
|
@ -1319,7 +1320,7 @@ int sanei_canon_pp_sleep_scanner(struct parport *port)
|
|||
/* expect(port, "Enter Transparent Mode", 0x1f, 0x1f, 1000000); */
|
||||
}
|
||||
|
||||
int sanei_canon_pp_detect(struct parport *port)
|
||||
int sanei_canon_pp_detect(struct parport *port, int mode)
|
||||
{
|
||||
/*int caps;*/
|
||||
/* This code needs to detect whether or not a scanner is present on
|
||||
|
@ -1342,7 +1343,7 @@ int sanei_canon_pp_detect(struct parport *port)
|
|||
DBG(0,"detect: Unable to claim port\n");
|
||||
return 2;
|
||||
}
|
||||
if (sanei_canon_pp_wake_scanner(port))
|
||||
if (sanei_canon_pp_wake_scanner(port, mode))
|
||||
{
|
||||
DBG(10, "detect: could not wake scanner\n");
|
||||
ieee1284_release(port);
|
||||
|
|
|
@ -75,6 +75,11 @@
|
|||
/* Scanner things */
|
||||
#define CALSIZE 18 /* Lines per calibration */
|
||||
|
||||
/* Init modes */
|
||||
#define INITMODE_20P 1
|
||||
#define INITMODE_30P 2
|
||||
#define INITMODE_AUTO 3
|
||||
|
||||
/* Misc things */
|
||||
#define T_SCAN 1
|
||||
#define T_CALIBRATE 2
|
||||
|
@ -148,7 +153,7 @@ typedef struct image_segment_struct
|
|||
|
||||
/* Brings the scanner in and out of transparent mode
|
||||
and detects model information */
|
||||
int sanei_canon_pp_initialise(scanner_parameters *sp);
|
||||
int sanei_canon_pp_initialise(scanner_parameters *sp, int mode);
|
||||
int sanei_canon_pp_close_scanner(scanner_parameters *sp);
|
||||
|
||||
/* Image scanning functions */
|
||||
|
@ -170,7 +175,7 @@ int sanei_canon_pp_calibrate(scanner_parameters *sp, char *cal_file);
|
|||
int sanei_canon_pp_adjust_gamma(scanner_parameters *sp);
|
||||
|
||||
/* Detect if a scanner is present on a given port */
|
||||
int sanei_canon_pp_detect(struct parport *port);
|
||||
int sanei_canon_pp_detect(struct parport *port, int mode);
|
||||
|
||||
/* Put a scanner to sleep */
|
||||
int sanei_canon_pp_sleep_scanner(struct parport *port);
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
/* No SANE, Things that only apply to stand-alone */
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
static void DBG(int level, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
@ -101,10 +102,8 @@ static void scanner_chessboard_control(struct parport *port);
|
|||
static void scanner_chessboard_data(struct parport *port, int mode);
|
||||
|
||||
/* Used by read_data */
|
||||
static int ieee_negotiation(struct parport *port, int e);
|
||||
static int ieee_transfer(struct parport *port, int length,
|
||||
unsigned char *data);
|
||||
static int scanner_endtransfer(struct parport *port);
|
||||
|
||||
/* Low level functions */
|
||||
static int readstatus(struct parport *port);
|
||||
|
@ -118,12 +117,19 @@ static void outboth(struct parport *port, int d, int c);
|
|||
|
||||
/************************************/
|
||||
|
||||
/*
|
||||
* IEEE 1284 defines many values for m,
|
||||
* but these scanners only support 2: nibble and ECP modes.
|
||||
* And no data compression either (argh!)
|
||||
* 0 = Nibble-mode reverse channel transfer
|
||||
* 16 = ECP-mode
|
||||
*/
|
||||
void sanei_canon_pp_set_ieee1284_mode(int m)
|
||||
{
|
||||
ieee_mode = m;
|
||||
}
|
||||
|
||||
int sanei_canon_pp_wake_scanner(struct parport *port)
|
||||
int sanei_canon_pp_wake_scanner(struct parport *port, int mode)
|
||||
{
|
||||
/* The scanner tristates the printer's control lines
|
||||
(essentially disabling the passthrough port) and exits
|
||||
|
@ -134,13 +140,20 @@ int sanei_canon_pp_wake_scanner(struct parport *port)
|
|||
|
||||
tmp = readstatus(port);
|
||||
|
||||
if ((tmp != READY))
|
||||
/* Reset only works on 30/40 models */
|
||||
if (mode != INITMODE_20P)
|
||||
{
|
||||
DBG(40, "Scanner not ready (0x%x). Attempting to reset...\n",
|
||||
tmp);
|
||||
scanner_reset(port);
|
||||
/* give it more of a chance to reset in this case */
|
||||
max_cycles = 5;
|
||||
if ((tmp != READY))
|
||||
{
|
||||
DBG(40, "Scanner not ready (0x%x). Attempting to "
|
||||
"reset...\n", tmp);
|
||||
scanner_reset(port);
|
||||
/* give it more of a chance to reset in this case */
|
||||
max_cycles = 5;
|
||||
}
|
||||
} else {
|
||||
DBG(0, "WARNING: Don't know how to reset an FBx20P, you may "
|
||||
"have to power cycle\n");
|
||||
}
|
||||
|
||||
do
|
||||
|
@ -149,13 +162,14 @@ int sanei_canon_pp_wake_scanner(struct parport *port)
|
|||
|
||||
/* Send the wakeup sequence */
|
||||
scanner_chessboard_control(port);
|
||||
scanner_chessboard_data(port, 1);
|
||||
scanner_chessboard_data(port, mode);
|
||||
|
||||
if (expect(port, NULL, 0x03, 0x1f, 800000))
|
||||
if (expect(port, NULL, 0x03, 0x1f, 800000) &&
|
||||
(mode == INITMODE_AUTO))
|
||||
{
|
||||
/* 630 Style init failed, try 620 style */
|
||||
scanner_chessboard_control(port);
|
||||
scanner_chessboard_data(port, 0);
|
||||
scanner_chessboard_data(port, INITMODE_20P);
|
||||
}
|
||||
|
||||
if (expect(port, "Scanner wakeup reply 1", 0x03, 0x1f, 50000))
|
||||
|
@ -211,21 +225,25 @@ int sanei_canon_pp_write(struct parport *port, int length, unsigned char *data)
|
|||
#endif
|
||||
|
||||
DBG(100, "NEW Send Command (length %i):\n", length);
|
||||
if (ieee_mode == M1284_ECP)
|
||||
ieee_negotiation(port, ieee_mode);
|
||||
|
||||
switch (ieee_mode)
|
||||
{
|
||||
case M1284_BECP:
|
||||
case M1284_ECPRLE:
|
||||
case M1284_ECPSWE:
|
||||
case M1284_ECP:
|
||||
ieee1284_negotiate(port, ieee_mode);
|
||||
if (ieee1284_ecp_write_data(port, 0, (char *)data,
|
||||
length) != length)
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
case M1284_NIBBLE:
|
||||
if (ieee1284_compat_write(port, 0, (char *)data,
|
||||
length) != length)
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
DBG(0, "Invalid mode in write!\n");
|
||||
}
|
||||
|
||||
DBG(100, "<< write");
|
||||
|
@ -238,10 +256,11 @@ int sanei_canon_pp_read(struct parport *port, int length, unsigned char *data)
|
|||
int count, offset;
|
||||
|
||||
DBG(200, "NEW read_data (%i bytes):\n", length);
|
||||
ieee_negotiation(port, ieee_mode);
|
||||
ieee1284_negotiate(port, ieee_mode);
|
||||
|
||||
/* This is special; Nibble mode needs a little
|
||||
extra help from us. */
|
||||
|
||||
if (ieee_mode == M1284_NIBBLE)
|
||||
{
|
||||
/* Interrupt phase */
|
||||
|
@ -249,7 +268,7 @@ int sanei_canon_pp_read(struct parport *port, int length, unsigned char *data)
|
|||
if (expect(port, "Read Data 1", 0, NDATAAVAIL, 6000000))
|
||||
{
|
||||
DBG(10,"Error 1\n");
|
||||
scanner_endtransfer(port);
|
||||
ieee1284_terminate(port);
|
||||
return 1;
|
||||
}
|
||||
outcont(port, HOSTBUSY, HOSTBUSY);
|
||||
|
@ -257,13 +276,13 @@ int sanei_canon_pp_read(struct parport *port, int length, unsigned char *data)
|
|||
if (expect(port, "Read Data 2", NACK, NACK, 1000000))
|
||||
{
|
||||
DBG(1,"Error 2\n");
|
||||
scanner_endtransfer(port);
|
||||
ieee1284_terminate(port);
|
||||
return 1;
|
||||
}
|
||||
if (expect(port, "Read Data 3 (Ready?)", 0, PERROR, 1000000))
|
||||
{
|
||||
DBG(1,"Error 3\n");
|
||||
scanner_endtransfer(port);
|
||||
ieee1284_terminate(port);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -272,7 +291,7 @@ int sanei_canon_pp_read(struct parport *port, int length, unsigned char *data)
|
|||
if ((readstatus(port) & NDATAAVAIL) == NDATAAVAIL)
|
||||
{
|
||||
DBG(1,"No data to read.\n");
|
||||
scanner_endtransfer(port);
|
||||
ieee1284_terminate(port);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -297,7 +316,7 @@ int sanei_canon_pp_read(struct parport *port, int length, unsigned char *data)
|
|||
if (count < 0) {
|
||||
DBG(10, "Couldn't read enough data (need %d more "
|
||||
"of %d)\n", length+count,length+offset);
|
||||
scanner_endtransfer(port);
|
||||
ieee1284_terminate(port);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -328,31 +347,13 @@ int sanei_canon_pp_read(struct parport *port, int length, unsigned char *data)
|
|||
}
|
||||
#endif
|
||||
|
||||
scanner_endtransfer(port);
|
||||
if (ieee_mode == M1284_NIBBLE)
|
||||
ieee1284_terminate(port);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* IEEE 1284 defines many values for e,
|
||||
* but these scanners only support 2: nibble and ECP modes.
|
||||
* And no data compression either (argh!)
|
||||
* 0 = Nibble-mode reverse channel transfer
|
||||
* 16 = ECP-mode
|
||||
*/
|
||||
static int ieee_negotiation(struct parport *port, int e)
|
||||
{
|
||||
int temp;
|
||||
|
||||
DBG(200, "IEEE Negotiation (mode %i)\n", e);
|
||||
|
||||
temp = ieee1284_negotiate(port, e);
|
||||
|
||||
DBG(200, "(result: %i)\n", temp);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
static int ieee_transfer(struct parport *port, int length, unsigned char *data)
|
||||
{
|
||||
int result = 0;
|
||||
|
@ -422,13 +423,6 @@ int sanei_canon_pp_check_status(struct parport *port)
|
|||
}
|
||||
}
|
||||
|
||||
/* This is a subfunction of scanner_readdata() */
|
||||
static int scanner_endtransfer(struct parport *port)
|
||||
{
|
||||
DBG(200, ">> IEEE Terminate\n");
|
||||
ieee1284_terminate(port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Send a raw byte to the printer port */
|
||||
static void outdata(struct parport *port, int d)
|
||||
|
@ -485,10 +479,10 @@ static void scanner_chessboard_data(struct parport *port, int mode)
|
|||
{
|
||||
/* Wiggle data lines (4 times) while strobing C1 */
|
||||
/* 33 here for *30P, 55 for *20P */
|
||||
if (mode)
|
||||
outdata(port, 0x33);
|
||||
else
|
||||
if (mode == INITMODE_20P)
|
||||
outdata(port, 0x55);
|
||||
else
|
||||
outdata(port, 0x33);
|
||||
outcont(port, HOSTBUSY, HOSTBUSY);
|
||||
usleep(10);
|
||||
outcont(port, 0, HOSTBUSY);
|
||||
|
@ -496,10 +490,10 @@ static void scanner_chessboard_data(struct parport *port, int mode)
|
|||
outcont(port, HOSTBUSY, HOSTBUSY);
|
||||
usleep(10);
|
||||
|
||||
if (mode)
|
||||
outdata(port, 0xcc);
|
||||
else
|
||||
if (mode == INITMODE_20P)
|
||||
outdata(port, 0xaa);
|
||||
else
|
||||
outdata(port, 0xcc);
|
||||
outcont(port, HOSTBUSY, HOSTBUSY);
|
||||
usleep(10);
|
||||
outcont(port, 0, HOSTBUSY);
|
||||
|
@ -517,9 +511,9 @@ static int scanner_reset(struct parport *port)
|
|||
if (readstatus(port) == 0x0b)
|
||||
{
|
||||
/* Init Block 1 - composed of a 0-byte IEEE read */
|
||||
ieee_negotiation(port, 0x0);
|
||||
ieee1284_negotiate(port, 0x0);
|
||||
ieee1284_terminate(port);
|
||||
ieee_negotiation(port, 0x0);
|
||||
ieee1284_negotiate(port, 0x0);
|
||||
ieee1284_terminate(port);
|
||||
scanner_chessboard_data(port, 1);
|
||||
scanner_chessboard_data(port, 1);
|
||||
|
@ -582,10 +576,10 @@ int sanei_canon_pp_scanner_init(struct parport *port)
|
|||
int tmp = 0;
|
||||
|
||||
/* Put the scanner in nibble mode */
|
||||
ieee_negotiation(port, 0x0);
|
||||
ieee1284_negotiate(port, 0x0);
|
||||
|
||||
/* No data to read yet - return to idle mode */
|
||||
scanner_endtransfer(port);
|
||||
ieee1284_terminate(port);
|
||||
|
||||
/* In Windows, this is always ECP (or an attempt at it) */
|
||||
if (sanei_canon_pp_write(port, 10, cmd_init))
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
|
||||
/* Actual Interface */
|
||||
void sanei_canon_pp_set_ieee1284_mode(int m);
|
||||
int sanei_canon_pp_wake_scanner(struct parport *port);
|
||||
int sanei_canon_pp_wake_scanner(struct parport *port, int mode);
|
||||
int sanei_canon_pp_write(struct parport *port, int length,
|
||||
unsigned char *data);
|
||||
int sanei_canon_pp_read(struct parport *port, int length,
|
||||
|
|
|
@ -293,7 +293,7 @@ sane_init (SANE_Int *vc, SANE_Auth_Callback cb)
|
|||
* us to call ieee1284_close in any of the remaining error
|
||||
* cases in this loop. */
|
||||
#if 0
|
||||
tmp = sanei_canon_pp_detect(s_tmp->params.port);
|
||||
tmp = sanei_canon_pp_detect(s_tmp->params.port, INITMODE_AUTO);
|
||||
|
||||
|
||||
if (tmp && (s_tmp->ieee1284_mode != M1284_NIBBLE))
|
||||
|
@ -304,7 +304,8 @@ sane_init (SANE_Int *vc, SANE_Auth_Callback cb)
|
|||
|
||||
s_tmp->ieee1284_mode = M1284_NIBBLE;
|
||||
sanei_canon_pp_set_ieee1284_mode(s_tmp->ieee1284_mode);
|
||||
tmp = sanei_canon_pp_detect(s_tmp->params.port);
|
||||
tmp = sanei_canon_pp_detect(s_tmp->params.port,
|
||||
INITMODE_AUTO);
|
||||
}
|
||||
/* still no go? */
|
||||
if (tmp)
|
||||
|
@ -327,7 +328,8 @@ sane_init (SANE_Int *vc, SANE_Auth_Callback cb)
|
|||
}
|
||||
|
||||
DBG(2, "sane_init: >> initialise\n");
|
||||
tmp = sanei_canon_pp_initialise(&(s_tmp->params));
|
||||
tmp = sanei_canon_pp_initialise(&(s_tmp->params),
|
||||
INITMODE_AUTO);
|
||||
DBG(2, "sane_init: << %d initialise\n", tmp);
|
||||
/* put it back to sleep until we're ready to
|
||||
* open for business again */
|
||||
|
@ -343,7 +345,8 @@ sane_init (SANE_Int *vc, SANE_Auth_Callback cb)
|
|||
|
||||
s_tmp->ieee1284_mode = M1284_NIBBLE;
|
||||
sanei_canon_pp_set_ieee1284_mode(s_tmp->ieee1284_mode);
|
||||
tmp = sanei_canon_pp_initialise(&(s_tmp->params));
|
||||
tmp = sanei_canon_pp_initialise(&(s_tmp->params),
|
||||
INITMODE_AUTO);
|
||||
}
|
||||
if (tmp) {
|
||||
DBG(10, "sane_init: Couldn't contact scanner on port "
|
||||
|
@ -524,7 +527,7 @@ sane_open (SANE_String_Const name, SANE_Handle *h)
|
|||
/* I put the scanner to sleep before, better wake it back up */
|
||||
|
||||
DBG(2, "sane_open: >> initialise\n");
|
||||
tmp = sanei_canon_pp_initialise(&(cs->params));
|
||||
tmp = sanei_canon_pp_initialise(&(cs->params), INITMODE_AUTO);
|
||||
DBG(2, "sane_open: << %d initialise\n", tmp);
|
||||
if (tmp != 0) {
|
||||
DBG(1, "sane_open: initialise returned %d, something is "
|
||||
|
|
|
@ -23,12 +23,12 @@
|
|||
:model "CanoScan FB310P" ; name models for above-specified mfg.
|
||||
:interface "Parport (ECP)"
|
||||
:status :unsupported
|
||||
:comment "Need a scanner to work on"
|
||||
:comment "Rebadged Avision, different command set"
|
||||
|
||||
:model "CanoScan FB610P" ; name models for above-specified mfg.
|
||||
:interface "Parport (ECP)"
|
||||
:status :unsupported
|
||||
:comment "Need a scanner to work on"
|
||||
:comment "Rebadged Avision, different command set"
|
||||
|
||||
:model "CanoScan FB320P" ; name models for above-specified mfg.
|
||||
:interface "Parport (ECP)"
|
||||
|
|
|
@ -28,9 +28,9 @@ CanoScan N640P ex
|
|||
No USB scanners are supported and there are no plans to support them in the
|
||||
future. Other projects are working on support for USB scanners. See the
|
||||
.B PROJECTS
|
||||
file for more detail. We cannot add support for the FB310P and FB610P at the
|
||||
moment, but contact us if you have one of these scanners and would really
|
||||
like to help.
|
||||
file for more detail. The FB310P and FB610P are rebadged Avision scanners
|
||||
which use a different command set, so are unlikely to be supported by this
|
||||
backend in the future.
|
||||
.PP
|
||||
IMPORTANT: this is alpha code. While we have made every effort to make it as
|
||||
reliable as possible, it will not always work as expected. Feedback is still
|
||||
|
|
Ładowanie…
Reference in New Issue