Added pixma_get_device_status()

merge-requests/1/head
Wittawat Yamwong 2006-06-03 00:34:36 +00:00
rodzic 7d49f55a82
commit aee4144acc
7 zmienionych plików z 235 dodań i 82 usunięć

Wyświetl plik

@ -43,46 +43,45 @@
#ifndef PIXMA_H
#define PIXMA_H
/*! \mainpage Scanner driver for Canon PIXMA MP series
\section example Sample code for application
\code
pixma_set_debug_level(level);
pixma_init();
nscanners = pixma_find_scanners();
devnr = choose_scanner(nscanners);
scanner = pixma_open(devnr);
setup_param(param);
pixma_check_scan_param(scanner, param);
do {
if (I_need_events &&
(ev = pixma_wait_event(scanner, timeout)) > 0) {
handle_event(ev);
}
pixma_scan(scanner, param);
while ((count = pixma_read_image(scanner, buf, len)) > 0) {
write(buf, count);
if (error_occured_in_write) {
pixma_cancel(scanner);
}
}
} while (!enough);
pixma_close(scanner);
pixma_cleanup();
\endcode
<b>Note:</b> pixma_cancel() can be called asynchronously to
interrupt pixma_read_image(). It does not cancel the operation
immediately. pixma_read_image() <em>must</em> be called until it
returns zero or an error (probably \c -ECANCELED).
\section reference Reference
- \subpage API
- \subpage IO
- \subpage subdriver
- \subpage debug
*/
/*!
* \mainpage Scanner driver for Canon PIXMA MP series
* \section example Sample code for application
* \code
* pixma_set_debug_level(level);
* pixma_init();
* nscanners = pixma_find_scanners();
* devnr = choose_scanner(nscanners);
* scanner = pixma_open(devnr);
* setup_param(param);
* pixma_check_scan_param(scanner, param);
* do {
* if (I_need_events &&
* (ev = pixma_wait_event(scanner, timeout)) > 0) {
* handle_event(ev);
* }
* pixma_scan(scanner, param);
* while ((count = pixma_read_image(scanner, buf, len)) > 0) {
* write(buf, count);
* if (error_occured_in_write) {
* pixma_cancel(scanner);
* }
* }
* } while (!enough);
* pixma_close(scanner);
* pixma_cleanup();
* \endcode
*
* <b>Note:</b> pixma_cancel() can be called asynchronously to
* interrupt pixma_read_image(). It does not cancel the operation
* immediately. pixma_read_image() <em>must</em> be called until it
* returns zero or an error (probably \c -ECANCELED).
*
* \section reference Reference
* - \subpage API
* - \subpage IO
* - \subpage subdriver
* - \subpage debug
*/
/*!
* \defgroup API The driver API
@ -137,9 +136,10 @@ typedef u_int32_t uint32_t;
#define PIXMA_CAP_EASY_RGB (1 << 0)
#define PIXMA_CAP_GRAY (1 << 1)
#define PIXMA_CAP_ADF (1 << 2)
#define PIXMA_CAP_16BIT (1 << 3)
#define PIXMA_CAP_48BIT (1 << 3)
#define PIXMA_CAP_GAMMA_TABLE (1 << 4)
#define PIXMA_CAP_EVENTS (1 << 5)
#define PIXMA_CAP_TPU (1 << 6)
#define PIXMA_CAP_EXPERIMENT (1 << 31)
/**@}*/
@ -159,6 +159,7 @@ struct pixma_scan_param_t;
struct pixma_config_t;
struct pixma_cmdbuf_t;
struct pixma_imagebuf_t;
struct pixma_device_status_t;
typedef struct pixma_t pixma_t;
typedef struct pixma_scan_ops_t pixma_scan_ops_t;
@ -166,6 +167,7 @@ typedef struct pixma_scan_param_t pixma_scan_param_t;
typedef struct pixma_config_t pixma_config_t;
typedef struct pixma_cmdbuf_t pixma_cmdbuf_t;
typedef struct pixma_imagebuf_t pixma_imagebuf_t;
typedef struct pixma_device_status_t pixma_device_status_t;
/** \addtogroup API
@ -185,6 +187,46 @@ typedef enum pixma_paper_source_t
PIXMA_SOURCE_ADF
} pixma_paper_source_t;
typedef enum pixma_hardware_status_t
{
PIXMA_HARDWARE_OK,
PIXMA_HARDWARE_ERROR
} pixma_hardware_status_t;
typedef enum pixma_lamp_status_t
{
PIXMA_LAMP_OK,
PIXMA_LAMP_WARMING_UP,
PIXMA_LAMP_OFF,
PIXMA_LAMP_ERROR
} pixma_lamp_status_t;
typedef enum pixma_adf_status_t
{
PIXMA_ADF_OK,
PIXMA_ADF_NO_PAPER,
PIXMA_ADF_JAMMED,
PIXMA_ADF_COVER_OPEN,
PIXMA_ADF_ERROR
} pixma_adf_status_t;
typedef enum pixma_calibration_status_t
{
PIXMA_CALIBRATION_OK,
PIXMA_CALIBRATION_IN_PROGRESS,
PIXMA_CALIBRATION_OFF,
PIXMA_CALIBRATION_ERROR
} pixma_calibration_status_t;
/** Device status. */
struct pixma_device_status_t
{
pixma_hardware_status_t hardware;
pixma_lamp_status_t lamp;
pixma_adf_status_t adf;
pixma_calibration_status_t cal;
};
/** Scan parameters. */
struct pixma_scan_param_t
{
@ -342,6 +384,12 @@ uint32_t pixma_wait_event (pixma_t *, int timeout);
* \see pixma_set_interrupt_mode() */
int pixma_enable_background (pixma_t *, int enabled);
/** Read the current device status.
* \param[out] status the current device status
* \return 0 if succeeded. Otherwise, failed.
*/
int pixma_get_device_status (pixma_t *, pixma_device_status_t * status);
const char *pixma_get_string (pixma_t *, pixma_string_index_t);
const pixma_config_t *pixma_get_config (pixma_t *);
void pixma_fill_gamma_table (double gamma, uint8_t * table, unsigned n);

Wyświetl plik

@ -611,7 +611,7 @@ pixma_wait_event (pixma_t * s, int timeout /*ms */ )
if (s->events == PIXMA_EV_NONE && s->ops->wait_event)
s->ops->wait_event (s, timeout);
events = s->events;
s->events = 0;
s->events = PIXMA_EV_NONE;
return events;
}
@ -710,3 +710,12 @@ pixma_get_device_model (unsigned devnr)
return (cfg) ? cfg->name : NULL;
}
int
pixma_get_device_status (pixma_t * s, pixma_device_status_t * status)
{
if (!status)
return -EINVAL;
memset (status, 0, sizeof (*status));
return s->ops->get_status (s, status);
}

Wyświetl plik

@ -161,6 +161,9 @@ struct pixma_scan_ops_t
/** Check the scan parameters. The parameters can be adjusted if they are
* out of range, e.g. width > max_width. */
int (*check_param) (pixma_t *, pixma_scan_param_t *);
/** Read the device status. \see pixma_get_device_status() */
int (*get_status) (pixma_t *, pixma_device_status_t *);
};

Wyświetl plik

@ -90,7 +90,10 @@ enum mp150_cmd_t
cmd_status = 0xf320,
cmd_abort_session = 0xef20,
cmd_time = 0xeb80,
cmd_read_image = 0xd420
cmd_read_image = 0xd420,
cmd_error_info = 0xff20, /* seen in MP800 */
cmd_e920 = 0xe920 /* " */
};
typedef struct mp150_t
@ -229,22 +232,21 @@ send_scan_param (pixma_t * s)
{
mp150_t *mp = (mp150_t *) s->subdriver;
uint8_t *data;
#if 0
unsigned raw_width;
/* NOTE: MP150 can cope with "unaligned" width. It always correctly
returns padded rows. Can other models do this, too? */
if (s->param->channels == 1)
raw_width = ALIGN (s->param->w, 12);
else
raw_width = ALIGN (s->param->w, 4);
/* FIXME: MP150 can cope with "unaligned" width. It always correctly
returns padded rows. Can other models do this, too? */
#endif
data = pixma_newcmd (&mp->cb, cmd_scan_param, 0x30, 0);
pixma_set_be16 (s->param->xdpi | 0x8000, data + 0x04);
pixma_set_be16 (s->param->ydpi | 0x8000, data + 0x06);
pixma_set_be32 (s->param->x, data + 0x08);
pixma_set_be32 (s->param->y, data + 0x0c);
pixma_set_be32 (s->param->w, data + 0x10);
pixma_set_be32 (raw_width, data + 0x10);
pixma_set_be32 (s->param->h, data + 0x14);
data[0x18] = (s->param->channels == 1) ? 0x04 : 0x08;
data[0x19] = s->param->channels * s->param->depth; /* bits per pixel */
@ -645,6 +647,21 @@ mp150_wait_event (pixma_t * s, int timeout)
}
}
static int
mp150_get_status (pixma_t * s, pixma_device_status_t * status)
{
int error;
error = query_status (s);
if (error < 0)
return error;
status->hardware = PIXMA_HARDWARE_OK;
status->adf = (has_paper (s)) ? PIXMA_ADF_OK : PIXMA_ADF_NO_PAPER;
status->cal =
(is_calibrated (s)) ? PIXMA_CALIBRATION_OK : PIXMA_CALIBRATION_OFF;
return 0;
}
static const pixma_scan_ops_t pixma_mp150_ops = {
mp150_open,
mp150_close,
@ -652,7 +669,8 @@ static const pixma_scan_ops_t pixma_mp150_ops = {
mp150_fill_buffer,
mp150_finish_scan,
mp150_wait_event,
mp150_check_param
mp150_check_param,
mp150_get_status
};
#define DEVICE(name, pid, dpi, cap) { \
@ -665,15 +683,17 @@ static const pixma_scan_ops_t pixma_mp150_ops = {
PIXMA_CAP_EASY_RGB|PIXMA_CAP_GRAY| \
PIXMA_CAP_GAMMA_TABLE|PIXMA_CAP_EVENTS|cap \
}
const pixma_config_t pixma_mp150_devices[] = {
DEVICE ("Canon PIXMA MP150", 0x1709, 1200, 0),
DEVICE ("Canon PIXMA MP170", 0x170a, 1200, 0),
DEVICE ("Canon PIXMA MP450", 0x170b, 1200, 0),
DEVICE ("Canon PIXMA MP500", 0x170c, 1200, 0),
/* TODO: check MP830 & MP800 limits & cap */
DEVICE ("Canon PIXMA MP800", 0x170d, 2400,
PIXMA_CAP_ADF | PIXMA_CAP_EXPERIMENT),
DEVICE ("Canon PIXMA MP830", 0x1713, 2400,
DEVICE ("Canon PIXMA MP530", 0xffff, 1200,
PIXMA_CAP_ADF | PIXMA_CAP_EXPERIMENT),
DEVICE ("Canon PIXMA MP800", 0x170d, 2400, PIXMA_CAP_TPU),
DEVICE ("Canon PIXMA MP800R", 0xffff, 2400,
PIXMA_CAP_TPU | PIXMA_CAP_EXPERIMENT),
DEVICE ("Canon PIXMA MP830", 0x1713, 2400, PIXMA_CAP_ADF),
DEVICE (NULL, 0, 0, 0)
};

Wyświetl plik

@ -169,7 +169,6 @@ send_scan_param (pixma_t * s)
{
mp730_t *mp = (mp730_t *) s->subdriver;
uint8_t *data;
unsigned mode;
data = pixma_newcmd (&mp->cb, cmd_scan_param, 0x2e, 0);
pixma_set_be16 (s->param->xdpi | 0x1000, data + 0x04);
@ -178,8 +177,8 @@ send_scan_param (pixma_t * s)
pixma_set_be32 (s->param->y, data + 0x0c);
pixma_set_be32 (mp->raw_width, data + 0x10);
pixma_set_be32 (s->param->h, data + 0x14);
mode = (s->param->channels == 1) ? 0x0408 : 0x0818;
pixma_set_be16 (mode, data + 0x18);
data[0x18] = (s->param->channels == 1) ? 0x04 : 0x08;
data[0x19] = s->param->channels * s->param->depth; /* bits per pixel */
data[0x1f] = 0x7f;
data[0x20] = 0xff;
data[0x23] = 0x81;
@ -227,6 +226,37 @@ read_image_block (pixma_t * s, uint8_t * header, uint8_t * data)
return datalen;
}
static int
send_time (pixma_t * s)
{
/* TODO */
UNUSED (s);
return 0;
}
static int
handle_interrupt (pixma_t * s, int timeout)
{
uint8_t buf[16];
int len;
len = pixma_wait_interrupt (s->io, buf, sizeof (buf), timeout);
if (len == -ETIMEDOUT)
return 0;
if (len < 0)
return len;
if (len != 8)
{
PDBG (pixma_dbg (1, "WARNING:unexpected interrupt packet length %d\n",
len));
return -EPROTO;
}
if (buf[5] & 8)
send_time (s);
return 1;
}
static int
step1 (pixma_t * s)
{
@ -307,14 +337,14 @@ mp730_close (pixma_t * s)
static unsigned
calc_raw_width (const pixma_t * s, const pixma_scan_param_t * sp)
{
unsigned raw_width, maxw;
unsigned raw_width;
/* FIXME: Does MP730 need the alignment? */
UNUSED (s);
if (sp->channels == 1)
raw_width = ALIGN (sp->w, 12);
else
raw_width = ALIGN (sp->w, 4);
maxw = s->cfg->width * (sp->xdpi / 75);
return (raw_width < maxw) ? raw_width : maxw;
return raw_width;
}
static int
@ -461,6 +491,29 @@ mp730_finish_scan (pixma_t * s)
}
}
static void
mp730_wait_event (pixma_t * s, int timeout)
{
/* FIXME: timeout is not correct. See usbGetCompleteUrbNoIntr() for
* instance. */
while (s->events == 0 && handle_interrupt (s, timeout) > 0)
{
}
}
static int
mp730_get_status (pixma_t * s, pixma_device_status_t * status)
{
int error;
error = query_status (s);
if (error < 0)
return error;
status->hardware = PIXMA_HARDWARE_OK;
status->adf = (has_paper (s)) ? PIXMA_ADF_OK : PIXMA_ADF_NO_PAPER;
return 0;
}
static const pixma_scan_ops_t pixma_mp730_ops = {
mp730_open,
@ -468,8 +521,9 @@ static const pixma_scan_ops_t pixma_mp730_ops = {
mp730_scan,
mp730_fill_buffer,
mp730_finish_scan,
NULL /*mp730_wait_event */ ,
mp730_check_param
mp730_wait_event,
mp730_check_param,
mp730_get_status
};
#define DEVICE(name, pid, dpi, w, h, cap) { \
@ -483,8 +537,8 @@ static const pixma_scan_ops_t pixma_mp730_ops = {
}
const pixma_config_t pixma_mp730_devices[] = {
/* TODO: check area limits */
DEVICE ("Canon MultiPASS MP700", 0x2630, 1200, 637, 877, 0),
DEVICE ("Canon MultiPASS MP730", 0x262f, 1200, 637, 870,
DEVICE ("Canon MultiPASS MP700", 0x2630, 1200, 638, 877, 0),
DEVICE ("Canon MultiPASS MP730", 0x262f, 1200, 638, 868,
PIXMA_CAP_ADF | PIXMA_CAP_EXPERIMENT),
DEVICE (NULL, 0, 0, 0, 0, 0)
};

Wyświetl plik

@ -210,23 +210,21 @@ send_scan_param (pixma_t * s)
{
mp750_t *mp = (mp750_t *) s->subdriver;
uint8_t *data;
unsigned mode;
mode = 0x0818;
data = pixma_newcmd (&mp->cb, cmd_scan_param, 0x2e, 0);
pixma_set_be16 (s->param->xdpi | 0x8000, data + 4);
pixma_set_be16 (s->param->ydpi | 0x8000, data + 6);
pixma_set_be32 (s->param->x, data + 8);
pixma_set_be32 (s->param->y, data + 12);
pixma_set_be32 (mp->raw_width, data + 16);
pixma_set_be32 (mp->raw_height, data + 20);
pixma_set_be16 (mode, data + 24);
data[32] = 0xff;
data[35] = 0x81;
data[38] = 0x02;
data[39] = 0x01;
data[41] = mp->monochrome ? 0 : 1;
pixma_set_be16 (s->param->xdpi | 0x8000, data + 0x04);
pixma_set_be16 (s->param->ydpi | 0x8000, data + 0x06);
pixma_set_be32 (s->param->x, data + 0x08);
pixma_set_be32 (s->param->y, data + 0x0c);
pixma_set_be32 (mp->raw_width, data + 0x10);
pixma_set_be32 (mp->raw_height, data + 0x14);
data[0x18] = 8; /* 8 = color, 4 = grayscale(?) */
data[0x19] = s->param->channels * s->param->depth;
data[0x20] = 0xff;
data[0x23] = 0x81;
data[0x26] = 0x02;
data[0x27] = 0x01;
data[0x29] = mp->monochrome ? 0 : 1;
return pixma_exec (s, &mp->cb);
}
@ -684,6 +682,23 @@ mp750_wait_event (pixma_t * s, int timeout)
}
}
static int
mp750_get_status (pixma_t * s, pixma_device_status_t * status)
{
int error;
error = query_status (s);
if (error < 0)
return error;
status->hardware = PIXMA_HARDWARE_OK;
status->adf = (has_paper (s)) ? PIXMA_ADF_OK : PIXMA_ADF_NO_PAPER;
status->cal =
(is_calibrated (s)) ? PIXMA_CALIBRATION_OK : PIXMA_CALIBRATION_OFF;
status->lamp = (is_warming_up (s)) ? PIXMA_LAMP_WARMING_UP : PIXMA_LAMP_OK;
return 0;
}
static const pixma_scan_ops_t pixma_mp750_ops = {
mp750_open,
mp750_close,
@ -691,7 +706,8 @@ static const pixma_scan_ops_t pixma_mp750_ops = {
mp750_fill_buffer,
mp750_finish_scan,
mp750_wait_event,
mp750_check_param
mp750_check_param,
mp750_get_status
};
/* FIXME: What is the maximum resolution? 2400 DPI?*/
@ -703,12 +719,14 @@ static const pixma_scan_ops_t pixma_mp750_ops = {
&pixma_mp750_ops, /* ops */ \
dpi, 2*(dpi), /* xdpi, ydpi */ \
638, 877, /* width, height */ \
PIXMA_CAP_ADF|cap \
cap \
}
const pixma_config_t pixma_mp750_devices[] = {
DEVICE ("Canon PIXMA MP750", 0x1706, 2400, PIXMA_CAP_EXPERIMENT),
DEVICE ("Canon PIXMA MP780", 0x1707, 2400, PIXMA_CAP_EXPERIMENT),
DEVICE ("Canon PIXMA MP750", 0x1706, 2400,
PIXMA_CAP_ADF | PIXMA_CAP_EXPERIMENT),
DEVICE ("Canon PIXMA MP780", 0x1707, 2400,
PIXMA_CAP_ADF | PIXMA_CAP_EXPERIMENT),
DEVICE ("Canon PIXMA MP760", 0x1708, 2400, PIXMA_CAP_EXPERIMENT),
DEVICE (NULL, 0, 0, 0)
};

Wyświetl plik

@ -70,6 +70,7 @@
#define pixma_get_device_config sanei_pixma_get_device_config
#define pixma_get_device_id sanei_pixma_get_device_id
#define pixma_get_device_model sanei_pixma_get_device_model
#define pixma_get_device_status sanei_pixma_get_device_status
#define pixma_get_string sanei_pixma_get_string
#define pixma_get_time sanei_pixma_get_time
#define pixma_hexdump sanei_pixma_hexdump