From ffb70517253b72a7caab9a607b2c4d8f8f4ec0ce Mon Sep 17 00:00:00 2001 From: "m. allan noah" Date: Sat, 29 Mar 2014 21:02:29 -0400 Subject: [PATCH] canon_dr backend v45 - dropout support for machines with ssm2 command - doublefeed support for machines with ssm2 command --- backend/canon_dr-cmd.h | 15 ++ backend/canon_dr.c | 357 +++++++++++++++++++++++++++-------------- backend/canon_dr.h | 1 + 3 files changed, 253 insertions(+), 120 deletions(-) diff --git a/backend/canon_dr-cmd.h b/backend/canon_dr-cmd.h index 3b5fec098..ff1ffc092 100644 --- a/backend/canon_dr-cmd.h +++ b/backend/canon_dr-cmd.h @@ -427,7 +427,10 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes) /* ==================================================================== */ /* Page codes used by GET/SET SCAN MODE 2 */ +#define SM2_pc_df 0x00 +#define SM2_pc_ultra 0x01 #define SM2_pc_buffer 0x02 +#define SM2_pc_dropout 0x06 /* ==================================================================== */ /* SET SCAN MODE 2 */ @@ -440,11 +443,23 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes) /* the payload */ #define SSM2_PAY_len 0x10 +/* for DF (0x00) page */ +#define set_SSM2_DF_thick(sb, val) setbitfield(sb+3, 1, 2, val) +#define set_SSM2_DF_len(sb, val) setbitfield(sb+3, 1, 0, val) + +/* for ULTRA (0x01) page */ +#define set_SSM2_ULTRA_top(sb, val) putnbyte(sb + 0x07, val, 2) +#define set_SSM2_ULTRA_bot(sb, val) putnbyte(sb + 0x09, val, 2) + /* for BUFFER (0x02) page */ #define set_SSM2_BUFF_unk(sb, val) sb[0x03] = val #define set_SSM2_BUFF_unk2(sb, val) sb[0x06] = val #define set_SSM2_BUFF_sync(sb, val) sb[0x09] = val +/* for DROPOUT (0x06) page */ +#define set_SSM2_DO_do(sb, val) sb[0x09] = val +#define set_SSM2_DO_en(sb, val) sb[0x0a] = val + /* ==================================================================== */ /* window descriptor macros for SET_WINDOW and GET_WINDOW */ diff --git a/backend/canon_dr.c b/backend/canon_dr.c index ac851c36e..89f8dc1f1 100644 --- a/backend/canon_dr.c +++ b/backend/canon_dr.c @@ -296,6 +296,9 @@ v44 2014-04-26, MAN - buffermode support for machines with ssm2 command - DR-M140 needs always_op=0 + v45 2014-04-29, MAN + - dropout support for machines with ssm2 command + - doublefeed support for machines with ssm2 command SANE FLOW DIAGRAM @@ -345,7 +348,7 @@ #include "canon_dr.h" #define DEBUG 1 -#define BUILD 44 +#define BUILD 45 /* values for SANE_DEBUG_CANON_DR env var: - errors 5 @@ -1463,6 +1466,7 @@ init_model (struct scanner *s) #endif s->rgb_format = 1; s->can_color = 1; + s->has_df_ultra = 1; s->color_inter_by_res[DPI_100] = COLOR_INTERLACE_GBR; s->color_inter_by_res[DPI_150] = COLOR_INTERLACE_GBR; @@ -3087,57 +3091,118 @@ ssm_df (struct scanner *s) { SANE_Status ret = SANE_STATUS_GOOD; - unsigned char cmd[SET_SCAN_MODE_len]; - size_t cmdLen = SET_SCAN_MODE_len; - - unsigned char out[SSM_PAY_len]; - size_t outLen = SSM_PAY_len; - DBG (10, "ssm_df: start\n"); - - if(!s->has_ssm || !s->has_df){ + + if(!s->has_df){ DBG (10, "ssm_df: unsupported, finishing\n"); return ret; } - - memset(cmd,0,cmdLen); - set_SCSI_opcode(cmd, SET_SCAN_MODE_code); - set_SSM_pf(cmd, 1); - set_SSM_pay_len(cmd, outLen); - - memset(out,0,outLen); - if(s->has_ssm_pay_head_len){ - set_SSM_pay_head_len(out, SSM_PAY_HEAD_len); - } - set_SSM_page_code(out, SM_pc_df); - set_SSM_page_len(out, SSM_PAGE_len); - - /* deskew by roller */ - if(s->rollerdeskew){ - set_SSM_DF_deskew_roll(out, 1); - } - /* staple detection */ - if(s->stapledetect){ - set_SSM_DF_staple(out, 1); - } + if(s->has_ssm){ - /* thickness */ - if(s->df_thickness){ - set_SSM_DF_thick(out, 1); - } + unsigned char cmd[SET_SCAN_MODE_len]; + size_t cmdLen = SET_SCAN_MODE_len; - /* length */ - if(s->df_length){ - set_SSM_DF_len(out, 1); + unsigned char out[SSM_PAY_len]; + size_t outLen = SSM_PAY_len; + + memset(cmd,0,cmdLen); + set_SCSI_opcode(cmd, SET_SCAN_MODE_code); + set_SSM_pf(cmd, 1); + set_SSM_pay_len(cmd, outLen); + + memset(out,0,outLen); + if(s->has_ssm_pay_head_len){ + set_SSM_pay_head_len(out, SSM_PAY_HEAD_len); + } + set_SSM_page_code(out, SM_pc_df); + set_SSM_page_len(out, SSM_PAGE_len); + + /* deskew by roller */ + if(s->rollerdeskew){ + set_SSM_DF_deskew_roll(out, 1); + } + + /* staple detection */ + if(s->stapledetect){ + set_SSM_DF_staple(out, 1); + } + + /* thickness */ + if(s->df_thickness){ + set_SSM_DF_thick(out, 1); + } + + /* length */ + if(s->df_length){ + set_SSM_DF_len(out, 1); + } + + ret = do_cmd ( + s, 1, 0, + cmd, cmdLen, + out, outLen, + NULL, NULL + ); + } - ret = do_cmd ( - s, 1, 0, - cmd, cmdLen, - out, outLen, - NULL, NULL - ); + else if(s->has_ssm2){ + + unsigned char cmd[SET_SCAN_MODE2_len]; + size_t cmdLen = SET_SCAN_MODE2_len; + + unsigned char out[SSM2_PAY_len]; + size_t outLen = SSM2_PAY_len; + + /* send ultrasonic offsets first */ + if(s->df_thickness && s->has_df_ultra){ + memset(cmd,0,cmdLen); + set_SCSI_opcode(cmd, SET_SCAN_MODE2_code); + set_SSM2_page_code(cmd, SM2_pc_ultra); + set_SSM2_pay_len(cmd, outLen); + + memset(out,0,outLen); + set_SSM2_ULTRA_top(out, 0); + set_SSM2_ULTRA_bot(out, 0); + + ret = do_cmd ( + s, 1, 0, + cmd, cmdLen, + out, outLen, + NULL, NULL + ); + } + + memset(cmd,0,cmdLen); + set_SCSI_opcode(cmd, SET_SCAN_MODE2_code); + set_SSM2_page_code(cmd, SM2_pc_df); + set_SSM2_pay_len(cmd, outLen); + + memset(out,0,outLen); + + /* thickness */ + if(s->df_thickness){ + set_SSM2_DF_thick(out, 1); + } + + /* length */ + if(s->df_length){ + set_SSM2_DF_len(out, 1); + } + + ret = do_cmd ( + s, 1, 0, + cmd, cmdLen, + out, outLen, + NULL, NULL + ); + + } + + else{ + DBG (10, "ssm_df: unsupported\n"); + } DBG (10, "ssm_df: finish\n"); @@ -3149,94 +3214,146 @@ ssm_do (struct scanner *s) { SANE_Status ret = SANE_STATUS_GOOD; - unsigned char cmd[SET_SCAN_MODE_len]; - size_t cmdLen = SET_SCAN_MODE_len; + DBG (10, "ssm_do: start\n"); - unsigned char out[SSM_PAY_len]; - size_t outLen = SSM_PAY_len; + if(!s->can_color){ + DBG (10, "ssm_do: unsupported, finishing\n"); + return ret; + } + + if(s->has_ssm){ - DBG (10, "ssm_do: start\n"); + unsigned char cmd[SET_SCAN_MODE_len]; + size_t cmdLen = SET_SCAN_MODE_len; + + unsigned char out[SSM_PAY_len]; + size_t outLen = SSM_PAY_len; + + memset(cmd,0,cmdLen); + set_SCSI_opcode(cmd, SET_SCAN_MODE_code); + set_SSM_pf(cmd, 1); + set_SSM_pay_len(cmd, outLen); + + memset(out,0,outLen); + if(s->has_ssm_pay_head_len){ + set_SSM_pay_head_len(out, SSM_PAY_HEAD_len); + } + set_SSM_page_code(out, SM_pc_dropout); + set_SSM_page_len(out, SSM_PAGE_len); + + set_SSM_DO_unk1(out, 0x03); + + switch(s->dropout_color_f){ + case COLOR_RED: + set_SSM_DO_unk2(out, 0x05); + set_SSM_DO_f_do(out,SSM_DO_red); + break; + case COLOR_GREEN: + set_SSM_DO_unk2(out, 0x05); + set_SSM_DO_f_do(out,SSM_DO_green); + break; + case COLOR_BLUE: + set_SSM_DO_unk2(out, 0x05); + set_SSM_DO_f_do(out,SSM_DO_blue); + break; + case COLOR_EN_RED: + set_SSM_DO_unk2(out, 0x05); + set_SSM_DO_f_en(out,SSM_DO_red); + break; + case COLOR_EN_GREEN: + set_SSM_DO_unk2(out, 0x05); + set_SSM_DO_f_en(out,SSM_DO_green); + break; + case COLOR_EN_BLUE: + set_SSM_DO_unk2(out, 0x05); + set_SSM_DO_f_en(out,SSM_DO_blue); + break; + } + + switch(s->dropout_color_b){ + case COLOR_RED: + set_SSM_DO_unk2(out, 0x05); + set_SSM_DO_b_do(out,SSM_DO_red); + break; + case COLOR_GREEN: + set_SSM_DO_unk2(out, 0x05); + set_SSM_DO_b_do(out,SSM_DO_green); + break; + case COLOR_BLUE: + set_SSM_DO_unk2(out, 0x05); + set_SSM_DO_b_do(out,SSM_DO_blue); + break; + case COLOR_EN_RED: + set_SSM_DO_unk2(out, 0x05); + set_SSM_DO_b_en(out,SSM_DO_red); + break; + case COLOR_EN_GREEN: + set_SSM_DO_unk2(out, 0x05); + set_SSM_DO_b_en(out,SSM_DO_green); + break; + case COLOR_EN_BLUE: + set_SSM_DO_unk2(out, 0x05); + set_SSM_DO_b_en(out,SSM_DO_blue); + break; + } + + ret = do_cmd ( + s, 1, 0, + cmd, cmdLen, + out, outLen, + NULL, NULL + ); - if(!s->has_ssm || !s->can_color){ - DBG (10, "ssm_do: unsupported, finishing\n"); - return ret; } - memset(cmd,0,cmdLen); - set_SCSI_opcode(cmd, SET_SCAN_MODE_code); - set_SSM_pf(cmd, 1); - set_SSM_pay_len(cmd, outLen); + else if(s->has_ssm2){ - memset(out,0,outLen); - if(s->has_ssm_pay_head_len){ - set_SSM_pay_head_len(out, SSM_PAY_HEAD_len); - } - set_SSM_page_code(out, SM_pc_dropout); - set_SSM_page_len(out, SSM_PAGE_len); + unsigned char cmd[SET_SCAN_MODE2_len]; + size_t cmdLen = SET_SCAN_MODE2_len; + + unsigned char out[SSM2_PAY_len]; + size_t outLen = SSM2_PAY_len; + + memset(cmd,0,cmdLen); + set_SCSI_opcode(cmd, SET_SCAN_MODE2_code); + set_SSM2_page_code(cmd, SM2_pc_dropout); + set_SSM2_pay_len(cmd, outLen); + + memset(out,0,outLen); + + switch(s->dropout_color_f){ + case COLOR_RED: + set_SSM2_DO_do(out,SSM_DO_red); + break; + case COLOR_GREEN: + set_SSM2_DO_do(out,SSM_DO_green); + break; + case COLOR_BLUE: + set_SSM2_DO_do(out,SSM_DO_blue); + break; + case COLOR_EN_RED: + set_SSM2_DO_en(out,SSM_DO_red); + break; + case COLOR_EN_GREEN: + set_SSM2_DO_en(out,SSM_DO_green); + break; + case COLOR_EN_BLUE: + set_SSM2_DO_en(out,SSM_DO_blue); + break; + } - set_SSM_DO_unk1(out, 0x03); - - switch(s->dropout_color_f){ - case COLOR_RED: - set_SSM_DO_unk2(out, 0x05); - set_SSM_DO_f_do(out,SSM_DO_red); - break; - case COLOR_GREEN: - set_SSM_DO_unk2(out, 0x05); - set_SSM_DO_f_do(out,SSM_DO_green); - break; - case COLOR_BLUE: - set_SSM_DO_unk2(out, 0x05); - set_SSM_DO_f_do(out,SSM_DO_blue); - break; - case COLOR_EN_RED: - set_SSM_DO_unk2(out, 0x05); - set_SSM_DO_f_en(out,SSM_DO_red); - break; - case COLOR_EN_GREEN: - set_SSM_DO_unk2(out, 0x05); - set_SSM_DO_f_en(out,SSM_DO_green); - break; - case COLOR_EN_BLUE: - set_SSM_DO_unk2(out, 0x05); - set_SSM_DO_f_en(out,SSM_DO_blue); - break; + ret = do_cmd ( + s, 1, 0, + cmd, cmdLen, + out, outLen, + NULL, NULL + ); } - switch(s->dropout_color_b){ - case COLOR_RED: - set_SSM_DO_unk2(out, 0x05); - set_SSM_DO_b_do(out,SSM_DO_red); - break; - case COLOR_GREEN: - set_SSM_DO_unk2(out, 0x05); - set_SSM_DO_b_do(out,SSM_DO_green); - break; - case COLOR_BLUE: - set_SSM_DO_unk2(out, 0x05); - set_SSM_DO_b_do(out,SSM_DO_blue); - break; - case COLOR_EN_RED: - set_SSM_DO_unk2(out, 0x05); - set_SSM_DO_b_en(out,SSM_DO_red); - break; - case COLOR_EN_GREEN: - set_SSM_DO_unk2(out, 0x05); - set_SSM_DO_b_en(out,SSM_DO_green); - break; - case COLOR_EN_BLUE: - set_SSM_DO_unk2(out, 0x05); - set_SSM_DO_b_en(out,SSM_DO_blue); - break; + else{ + DBG (10, "ssm_do: unsupported\n"); } - ret = do_cmd ( - s, 1, 0, - cmd, cmdLen, - out, outLen, - NULL, NULL - ); - DBG (10, "ssm_do: finish\n"); return ret; diff --git a/backend/canon_dr.h b/backend/canon_dr.h index febaee027..4a19f55d8 100644 --- a/backend/canon_dr.h +++ b/backend/canon_dr.h @@ -180,6 +180,7 @@ struct scanner int has_comp_JPEG; int has_buffer; int has_df; + int has_df_ultra; int has_btc; int has_ssm; /* older scanners use this set scan mode command */ int has_ssm2; /* newer scanners user this similar command */