diff --git a/ChangeLog b/ChangeLog index f542af483..629dafd45 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2003-01-24 Gerhard Jaeger + * doc/plustek/Plustek-USB-TODO.txt + doc/plustek/Plustek-USB.txt + Documentation update + * doc/descriptions/plustek.desc: status updates + * backend/plustek.conf fixed options + * backend/plustek.c backend/plustek-devs.c backend/plustek-usb.c + backend/plustek-usbhw.c backend/plustek-usbimg.c + backend/plustek-usbscan.c backend/plustek-usbshading.c + backend/plustek.h backend/plustek-usb.h + Minor fixes and prototype description updates, code cleanup + 2003-01-23 Karl Heinz Kremer * doc/descriptions/epson.desc: Added Perfection 3200/GT-9800 @@ -183,7 +195,7 @@ * po/sane-backends.pt.po: Even more Portuguese translations from Pedro Morais . - * sanei/sanei_usb.c: Comment out resetep at sane_close. This + * sanei/sanei_usb.c: Comment out resetep at sane_close. This function sets th USB data toggle only on the host side. * TODO: Removed microtek2 problem, updated Irix patch section and Linux/Sparc section. diff --git a/backend/plustek-devs.c b/backend/plustek-devs.c index 498d151db..e682b3990 100644 --- a/backend/plustek-devs.c +++ b/backend/plustek-devs.c @@ -624,10 +624,10 @@ static DCapsDef Cap0x04A9_0x2206_0 = */ static DCapsDef Cap0x04A9_0x2207_0 = { - {{ 0, 85}, 35,-1, {2550, 3508}, {75, 75}, COLOR_BW }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 85}, 35, -1, {2550, 3508}, {75, 75}, COLOR_BW }, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, {1200, 1200}, 0, SENSORORDER_rgb, @@ -638,11 +638,11 @@ static DCapsDef Cap0x04A9_0x2207_0 = (_WAF_MISC_IO_LAMPS | _WAF_SKIP_WHITEFINE), _NO_MIO }; -/* Canon N670U/N676U +/* Canon N670U/N676U/LiDE20 */ static DCapsDef Cap0x04A9_0x220D_0 = { - {{ 0, 100}, 30, -1, {2550, 3508}, {75, 75}, COLOR_GRAY16 }, + {{ 0, 100}, 35, -1, {2550, 3508}, {75, 75}, COLOR_GRAY16 }, {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, @@ -660,10 +660,10 @@ static DCapsDef Cap0x04A9_0x220D_0 = */ static DCapsDef Cap0x04A9_0x220E_0 = { - {{ 0, 80}, 22,-1, {2550, 3508}, {75, 75}, COLOR_BW }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, - {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 100}, 35, -1, {2550, 3508}, {75, 75}, COLOR_BW }, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, + {{ 0, 0}, 0, 0, {0, 0}, { 0, 0 }, 0 }, {1200, 1200}, 0, SENSORORDER_rgb, @@ -1581,12 +1581,12 @@ static HWDef Hw0x04B8_0x010F_0 = 0x02, /* ok bSensorConfiguration (0x0b) */ 0x04, /* ok sensor control settings (reg 0x0c) */ - 0x7f, /* ok sensor control settings (reg 0x0d) */ - 0x13, /* ok sensor control settings (reg 0x0e) */ + 0x7d, /* ok sensor control settings (reg 0x0d) */ + 0x37, /* ok sensor control settings (reg 0x0e) */ - {0x02, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00}, - /* ?? mono (reg 0x0f to 0x18) */ - {0x06, 0x16, 0x00, 0x05, 0x0c, 0x17, 0x00, 0x00, 0x08, 0x14}, + {0x02, 0x07, 0x00, 0x01, 0x04, 0x07, 0x00, 0x00, 0x03, 0x07}, + /* ok mono (reg 0x0f to 0x18) */ + {0x06, 0x16, 0x00, 0x05, 0x0c, 0x17, 0x00, 0x00, 0x0a, 0x17}, /* ok color (reg 0x0f to 0x18) */ _GREEN_CH, /* ok bReg_0x26 color mode - bits 4 and 5 */ 0x40, /* ok bReg 0x27 color mode */ @@ -1599,7 +1599,7 @@ static HWDef Hw0x04B8_0x010F_0 = 0x00, /* ok bOpticBlackStart (reg 0x1c) */ 0x42, /* ok bOpticBlackEnd (reg 0x1d) */ 69, /* ok wActivePixelsStart (reg 0x1e + 0x1f) */ - 10766, /* ok wLineEnd (reg 0x20 + 0x21) */ + 10758, /* ok wLineEnd (reg 0x20 + 0x21) */ 16383, /* ok red lamp on (reg 0x2c + 0x2d) */ 0, /* ok red lamp off (reg 0x2e + 0x2f) */ @@ -1649,7 +1649,7 @@ static HWDef Hw0x04B8_0x011D_0 = 0x37, /* ok sensor control settings (reg 0x0e) */ {0x02, 0x07, 0x00, 0x01, 0x04, 0x07, 0x00, 0x00, 0x03, 0x07}, - /* ?? mono (reg 0x0f to 0x18) */ + /* ok mono (reg 0x0f to 0x18) */ {0x06, 0x0b, 0x00, 0x05, 0x0c, 0x17, 0x00, 0x00, 0x0a, 0x17}, /* ok color (reg 0x0f to 0x18) */ _GREEN_CH, /* ok bReg_0x26 color mode - bits 4 and 5 */ @@ -1853,8 +1853,8 @@ static HWDef Hw0x04A9_0x2206_0 = 0x00, /* bReg 0x27 color mode */ 2, /* bReg 0x29 illumination mode (runtime) */ /* illumination mode settings */ - { 3, 0, 0, 23, 1467, 0, 0 }, - { 2, 23, 2416, 23, 1801, 23, 1472 }, + { 3, 0, 0, 23, 1800, 0, 0 }, + { 2, 23, 4000, 23, 2600, 23, 1600 }, 1, /* StepperPhaseCorrection (reg 0x1a + 0x1b) */ 0, /* bOpticBlackStart (reg 0x1c) */ @@ -1862,6 +1862,8 @@ static HWDef Hw0x04A9_0x2206_0 = 89, /* ? wActivePixelsStart (reg 0x1e + 0x1f) */ 6074, /* wLineEnd (reg 0x20 + 0x21) */ +/* 0x17ba = 6074 bis 100dpi, 0x14ba = 5306 */ + 23, /* red lamp on (reg 0x2c + 0x2d) */ 2416, /* red lamp off (reg 0x2e + 0x2f) */ 23, /* green lamp on (reg 0x30 + 0x31) */ @@ -1887,7 +1889,7 @@ static HWDef Hw0x04A9_0x2206_0 = 0, /* test mode ADC Output CODE LSB (reg 0x5d) */ 0, /* test mode (reg 0x5e) */ _LM9832, - MODEL_CANON650 + MODEL_CANON600 }; /** Canon N1220U */ @@ -1956,14 +1958,14 @@ static HWDef Hw0x04A9_0x2207_0 = MODEL_CANON1220 }; -/** Canon 670/676 */ +/** Canon 670/676/LiDE20 */ static HWDef Hw0x04A9_0x220D_0 = { - 0.86, /* dMaxMotorSpeed (Max_Speed) */ - 0.21, /* dMaxMoveSpeed (Max_Speed) */ - 100, /* dIntegrationTimeLowLamp */ - 100, /* dIntegrationTimeHighLamp */ - 1200, /* wMotorDpi (Full step DPI) */ + 0.86, /* dMaxMotorSpeed (Max_Speed) */ + 0.243, /* dMaxMoveSpeed (Max_Speed) */ + 100, /* dIntegrationTimeLowLamp */ + 100, /* dIntegrationTimeHighLamp */ + 1200, /* wMotorDpi (Full step DPI) */ 512, /* wRAMSize (KB) */ 3.75, /* dMinIntegrationTimeLowres (ms) */ 5.75, /* dMinIntegrationTimeHighres (ms) */ @@ -1985,14 +1987,17 @@ static HWDef Hw0x04A9_0x220D_0 = 0x00, /* bReg 0x27 color mode */ 2, /* bReg 0x29 illumination mode (runtime) */ - { 3, 0, 0, 23, 5000, 0, 0 }, - { 2, 23, 4562, 23, 4315, 23, 3076 }, + + { 3, 0, 0, 23, 1800, 0, 0 }, + { 2, 23, 3562, 23, 3315, 23, 2676 }, 1, /* StepperPhaseCorrection (reg 0x1a + 0x1b) */ 0, /* bOpticBlackStart (reg 0x1c) */ 0, /* bOpticBlackEnd (reg 0x1d) */ 75, /* wActivePixelsStart (reg 0x1e + 0x1f) */ - 5293, /* wLineEnd (reg 0x20 + 0x21) */ + 6074, /* wLineEnd (reg 0x20 + 0x21) */ + +/* ??0x17ba = 6074 bis 100dpi, 0x14ba = 5306 */ 23, /* red lamp on (reg 0x2c + 0x2d) */ 4562, /* red lamp off (reg 0x2e + 0x2f) */ @@ -2003,7 +2008,7 @@ static HWDef Hw0x04A9_0x220D_0 = 3, /* stepper motor control (reg 0x45) */ 0, /* wStepsAfterPaperSensor2 (reg 0x4c + 0x4d) */ - 0, /* steps to reverse when buffer is full reg 0x50) */ + 0x3f, /* steps to reverse when buffer is full reg 0x50) */ 0xfc, /* acceleration profile (reg 0x51) */ 0, /* lines to process (reg 0x54) */ 0x0f, /* kickstart (reg 0x55) */ @@ -2019,7 +2024,7 @@ static HWDef Hw0x04A9_0x220D_0 = 0, /* test mode ADC Output CODE LSB (reg 0x5d) */ 0, /* test mode (reg 0x5e) */ _LM9833, - MODEL_CANON670 + MODEL_CANON600 }; /** Canon N1240U */ @@ -2051,25 +2056,27 @@ static HWDef Hw0x04A9_0x220E_0 = 0x00, /* bReg 0x27 color mode */ 2, /* bReg 0x29 illumination mode */ - { 3, 0, 0, 23, 3472, 0, 0 }, - { 2, 23, 10581, 23, 5304, 23, 3735 }, + { 3, 0, 0, 23, 3937, 0, 0 }, + { 2, 23, 12000, 23, 5500, 23, 3900 }, 1, /* StepperPhaseCorrection (reg 0x1a + 0x1b) */ 0, /* bOpticBlackStart (reg 0x1c) */ 0, /* bOpticBlackEnd (reg 0x1d) */ 52, /* wActivePixelsStart (reg 0x1e + 0x1f) */ - 10586, /* wLineEnd (reg 0x20 + 0x21) */ + 10586, /* wLineEnd (reg 0x20 + 0x21) */ + +/* 0x2f7a = 12154 bis 100dpi, 0x295a = 10586 */ 23, /* red lamp on (reg 0x2c + 0x2d) */ 10581, /* red lamp off (reg 0x2e + 0x2f) */ 23, /* green lamp on (reg 0x30 + 0x31) */ - 5304, /* green lamp off (reg 0x32 + 0x33) */ + 5096, /* green lamp off (reg 0x32 + 0x33) */ 23, /* blue lamp on (reg 0x34 + 0x35) */ 3735, /* blue lamp off (reg 0x36 + 0x37) */ 3, /* stepper motor control (reg 0x45) */ 0, /* wStepsAfterPaperSensor2 (reg 0x4c + 0x4d) */ - 0, /* steps to reverse when buffer is full reg 0x50) */ + 0x20, /* steps to reverse when buffer is full reg 0x50) */ 0xfc, /* acceleration profile (reg 0x51) */ 0, /* lines to process (reg 0x54) */ 0x0f, /* kickstart (reg 0x55) */ @@ -2149,8 +2156,8 @@ static SetDef Settings[] = /* CANON... */ {"0x04A9-0x2206", &Cap0x04A9_0x2206_0, &Hw0x04A9_0x2206_0, "N650U/N656U" }, {"0x04A9-0x2207", &Cap0x04A9_0x2207_0, &Hw0x04A9_0x2207_0, "N1220U" }, - {"0x04A9-0x220D", &Cap0x04A9_0x220D_0, &Hw0x04A9_0x220D_0, "N670U/N676U" }, - {"0x04A9-0x220E", &Cap0x04A9_0x220E_0, &Hw0x04A9_0x220E_0, "N1240U" }, + {"0x04A9-0x220D", &Cap0x04A9_0x220D_0, &Hw0x04A9_0x220D_0, "N670U/N676U/LiDE20" }, + {"0x04A9-0x220E", &Cap0x04A9_0x220E_0, &Hw0x04A9_0x220E_0, "N1240U/LiDE30" }, /* Please add other devices here... * The first entry is a string, composed out of the vendor and product id, @@ -2188,8 +2195,8 @@ static ClkMotorDef Motors[] = { 64, 20, 6, /* PWM, PWM_Duty, MCLK for fast move */ /* Motor settings (PWM and PWM_Duty) */ - {{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }}, + {{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, + { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }}, /* Color mode MCLK settings */ { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 }, { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 }, @@ -2200,8 +2207,8 @@ static ClkMotorDef Motors[] = { { MODEL_HuaLien, 64, 20, 6, /* Motor settings (PWM and PWM_Duty) */ - {{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }}, + {{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, + { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }}, /* Color mode MCLK settings */ { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 }, { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 }, @@ -2212,8 +2219,8 @@ static ClkMotorDef Motors[] = { { MODEL_Tokyo600, 4, 4, 6, /* Motor settings (PWM and PWM_Duty) */ - {{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }}, + {{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, + { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }}, /* Color mode MCLK settings */ { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 }, { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 }, @@ -2222,37 +2229,10 @@ static ClkMotorDef Motors[] = { { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 } }, - { MODEL_NOPLUSTEK_600, 64, 20, 6, - /* Motor settings (PWM and PWM_Duty) */ - {{ 16, 4 }, { 16, 4 }, { 16, 4 }, { 16, 4 }, { 16, 4 }, - { 16, 4 }, { 16, 4 }, { 16, 4 }, { 16, 4 }, { 16, 4 }}, - /* Color mode MCLK settings */ - { 4.0, 3.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 3.0 }, - { 4.0, 3.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0, 3.0 }, - /* Gray mode MCLK settings */ - { 3.0, 3.0, 3.0, 3.0, 3.0, 9.0, 9.0, 9.0, 9.0, 9.0 }, - { 3.0, 3.0, 3.0, 3.0, 3.0, 9.0, 9.0, 9.0, 9.0, 9.0 } - }, - - { MODEL_NOPLUSTEK_1200, 1, 48, 6, - /* Motor settings (PWM and PWM_Duty) */ - /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ - {{ 1, 48 }, { 1, 48 }, { 1, 48 }, { 1, 48 }, { 1, 48 }, - - /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ - { 2, 48 }, { 8, 48 }, { 2, 48 }, { 1, 48 }, { 1, 48 }}, - /* Color mode MCLK settings */ - { 2.0, 2.0, 2.0, 2.0, 2.0, 4.0, 4.0, 4.0, 5.5, 5.5 }, - { 2.0, 2.0, 2.0, 2.0, 2.0, 4.0, 4.0, 4.0, 5.5, 5.5 }, - /* Gray mode MCLK settings */ - { 5.0, 5.0, 5.0, 5.0, 5.0, 6.0, 6.0, 6.0, 6.0, 6.0 }, - { 5.0, 5.0, 5.0, 5.0, 5.0, 6.0, 6.0, 6.0, 6.0, 6.0 } - }, - { MODEL_MUSTEK600, 4, 4, 6, /* Motor settings (PWM and PWM_Duty) */ - {{ 16, 4 }, { 16, 4 }, { 16, 4 }, { 16, 4 }, { 16, 4 }, - { 16, 4 }, { 16, 4 }, { 16, 4 }, { 16, 4 }, { 16, 4 }}, + {{ 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, + { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }}, /* Color mode MCLK settings */ { 3.5, 3.5, 3.5, 4.0, 6.0, 8.0, 11.5, 11.5, 11.5, 11.5 }, { 3.5, 3.5, 3.5, 4.0, 6.0, 8.0, 11.5, 11.5, 11.5, 11.5 }, @@ -2263,11 +2243,11 @@ static ClkMotorDef Motors[] = { { MODEL_MUSTEK1200, 2, 32, 3, /* Motor settings (PWM and PWM_Duty) */ - /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ - {{ 2, 32 }, { 2, 32 }, { 2, 32 }, { 2, 32 }, { 2, 32 }, + /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ + {{ 2, 32, 1 }, { 2, 32, 1 }, { 2, 32, 1 }, { 2, 32, 1 }, { 2, 32, 1 }, - /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ - { 2, 32 }, { 2, 32 }, { 2, 32 }, { 2, 32 }, { 2, 32 }}, + /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ + { 2, 32, 1 }, { 2, 32, 1 }, { 2, 32, 1 }, { 2, 32, 1 }, { 2, 32, 1 }}, /* Color mode MCLK settings */ { 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5 }, { 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5 }, @@ -2279,8 +2259,8 @@ static ClkMotorDef Motors[] = { /* settings good for the HP models (tested with 2200)*/ { MODEL_HP, 8, 60, 6, /* Motor settings (PWM and PWM_Duty) */ - {{ 8, 60 }, { 8, 60 }, { 8, 60 }, { 8, 60 }, { 8, 60 }, - { 8, 60 }, { 8, 60 }, { 8, 60 }, { 8, 60 }, { 8, 60 }}, + {{ 8, 60, 1 }, { 8, 60, 1 }, { 8, 60, 1 }, { 8, 60, 1 }, { 8, 60, 1 }, + { 8, 60, 1 }, { 8, 60, 1 }, { 8, 60, 1 }, { 8, 60, 1 }, { 8, 60, 1 }}, /* Color mode MCLK settings */ { 4.0, 4.0, 4.0, 4.0, 3.0, 4.0, 6.0, 6.0, 6.0, 6.0 }, { 4.0, 4.0, 4.0, 4.0, 3.0, 4.0, 6.0, 6.0, 6.0, 6.0 }, @@ -2290,73 +2270,58 @@ static ClkMotorDef Motors[] = { { 8.0, 8.0, 8.0, 8.0, 8.0, 13.0, 13.0, 13.0, 13.0, 13.0 } }, - { MODEL_CANON650, 8, 51, 6, + { MODEL_CANON600, 8, 51, 6, /* Motor settings (PWM and PWM_Duty) */ - /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ - {{ 8, 31 }, { 8, 31 }, { 8, 31 }, { 8, 31 }, { 8, 31 }, + /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ + {{ 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, - /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ - { 8, 31 }, { 8, 31 }, { 8, 31 }, { 8, 31 }, { 8, 31 }}, - /* Color mode MCLK settings */ - { 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 2.0, 6.0, 6.0, 6.0 }, - { 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 2.0, 6.0, 6.0, 6.0 }, - - /* Gray mode MCLK settings */ - { 18.0, 15.0, 12.0, 12.0, 9.5, 6.5, 6.0, 6.0, 6.0, 6.0 }, - { 18.0, 15.0, 12.0, 12.0, 9.5, 6.5, 6.0, 6.0, 6.0, 6.0 } - }, - - { MODEL_CANON1220, 8, 51, 6, - /* Motor settings (PWM and PWM_Duty) */ - /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ - {{ 8, 31 }, { 8, 31 }, { 8, 31 }, { 8, 31 }, { 8, 31 }, - - /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ - { 8, 31 }, { 8, 31 }, { 8, 31 }, { 8, 31 }, { 8, 31 }}, + /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ + { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }}, /* Color mode MCLK settings */ { 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0 }, { 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0 }, - /* Gray mode MCLK settings */ - { 18.0, 15.0, 12.0, 12.0, 9.5, 6.5, 6.0, 6.0, 6.0, 6.0 }, - { 18.0, 15.0, 12.0, 12.0, 9.5, 6.5, 6.0, 6.0, 6.0, 6.0 } - }, - - { MODEL_CANON670, 8, 51, 6, - /* Motor settings (PWM and PWM_Duty) */ - /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ - {{ 8, 63 }, { 8, 31 }, { 8, 31 }, { 8, 31 }, { 6, 31 }, - - /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ - { 6, 31 }, { 6, 31 }, { 6, 31 }, { 6, 31 }, { 6, 31 }}, - /* Color mode MCLK settings */ - { 6.0, 5.0, 4.0, 4.0, 4.0, 2.0, 2.0, 2.0, 2.0, 2.0 }, - { 6.0, 5.0, 4.0, 4.0, 4.0, 2.0, 2.0, 2.0, 2.0, 2.0 }, - /* Gray mode MCLK settings */ - { 18.0, 15.0, 12.0, 12.0, 9.5, 6.5, 6.0, 6.0, 6.0, 6.0 }, - { 18.0, 15.0, 12.0, 12.0, 9.5, 6.5, 6.0, 6.0, 6.0, 6.0 } - }, - - { MODEL_CANON1240, 8, 31, 3, - /* Motor settings (PWM and PWM_Duty) */ - /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ - {{ 8, 31 }, { 8, 31 }, { 8, 31 }, { 8, 31 }, { 8, 31 }, - - /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ - { 8, 31 }, { 8, 31 }, { 8, 31 }, { 8, 31 }, { 8, 31 }}, - /* Color mode MCLK settings */ - { 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 2.0, 2.0, 2.0, 2.0 }, - { 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 2.0, 2.0, 2.0, 2.0 }, /* Gray mode MCLK settings */ { 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0 }, { 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0, 12.0 } }, + { MODEL_CANON1220, 8, 51, 6, + /* Motor settings (PWM and PWM_Duty) */ + /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ + {{ 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, + + /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ + { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }}, + /* Color mode MCLK settings */ + { 6.0, 6.0, 3.0, 3.0, 6.0, 6.0, 6.0, 6.0, 2.5, 6.0 }, + { 6.0, 6.0, 3.0, 3.0, 6.0, 6.0, 6.0, 6.0, 2.5, 6.0 }, + + /* Gray mode MCLK settings */ + { 18.0, 15.0, 12.0, 12.0, 9.5, 6.5, 6.0, 6.0, 6.0, 6.0 }, + { 18.0, 15.0, 12.0, 12.0, 9.5, 6.5, 6.0, 6.0, 6.0, 6.0 } + }, + + { MODEL_CANON1240, 8, 51, 3, + /* Motor settings (PWM and PWM_Duty) */ + /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ + {{ 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, + + /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ + { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }, { 8, 31, 1 }}, + /* Color mode MCLK settings */ + { 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0 }, + { 3.0, 3.0, 3.0, 3.0, 3.0, 3.0, 5.0, 6.0, 6.0, 6.0 }, + /* Gray mode MCLK settings */ + { 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0, 6.0 }, + { 6.5, 6.5, 6.0, 6.0, 6.0, 6.0, 8.0, 12.0, 12.0, 12.0 } + }, + /* settings good for the UMAX models (tested with 3400) */ { MODEL_UMAX, 16, 4, 6, /* Motor settings (PWM and PWM_Duty) */ - {{ 16, 4 }, { 16, 4 }, { 16, 4 }, { 16, 4 }, { 16, 4 }, - { 16, 4 }, { 16, 4 }, { 16, 4 }, { 16, 4 }, { 16, 4 }}, + {{ 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, + { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }, { 16, 4, 1 }}, /* Color mode MCLK settings */ { 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5 }, { 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5 }, @@ -2368,11 +2333,11 @@ static ClkMotorDef Motors[] = { /* settings good for the EPSON models (tested with 1260) */ { MODEL_EPSON, 2, 1, 6, /* Motor settings (PWM and PWM_Duty) */ - /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ - {{ 2, 1 }, { 2, 1 }, { 2, 1 }, { 2, 1 }, { 2, 1 }, + /* <=75dpi <=100dpi <=150dpi <=200dpi <=300dpi */ + {{ 2, 1, 1 }, { 2, 1, 1 }, { 2, 1, 1 }, { 2, 1, 1 }, { 2, 1, 1 }, - /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ - { 2, 1 }, { 2, 1 }, { 2, 1 }, { 2, 1 }, { 2, 1 }}, + /* <=400dpi <=600dpi <=800dpi <=1200dpi <=2400dpi */ + { 2, 1, 1 }, { 2, 1, 1 }, { 2, 1, 1 }, { 2, 1, 1 }, { 2, 1, 1 }}, /* Color mode MCLK settings */ { 2.0, 2.0, 2.0, 2.0, 2.0, 2.5, 3.0, 4.0, 6.0, 6.0 }, { 2.0, 2.0, 2.0, 2.0, 3.0, 2.5, 3.0, 4.0, 6.0, 6.0 }, diff --git a/backend/plustek-usb.c b/backend/plustek-usb.c index fd30e23b0..de324989d 100644 --- a/backend/plustek-usb.c +++ b/backend/plustek-usb.c @@ -946,21 +946,21 @@ static int usbDev_startScan( Plustek_Device *dev, pStartScan start ) return _E_ALLOC; } + /** * do the reading stuff here... * first we perform the calibration step, and then we read the image * line for line */ -static int usbDev_readImage( struct Plustek_Device *dev, - SANE_Byte *buf, unsigned long data_length ) +static int usbDev_Prepare( struct Plustek_Device *dev, SANE_Byte *buf ) { - int result, lines; - u_long dw, scaler; + int result; + u_long scaler; pScanDef scanning = &dev->scanning; pDCapsDef scaps = &dev->usbDev.Caps; pHWDef hw = &dev->usbDev.HwSetting; - DBG( _DBG_INFO, "usbDev_readImage()\n" ); + DBG( _DBG_INFO, "usbDev_PrepareScan()\n" ); /* check the current position of the sensor and move it back * to it's home position if necessary... @@ -1197,111 +1197,134 @@ static int usbDev_readImage( struct Plustek_Device *dev, dumpPic( "plustek-pic.raw", NULL, 0 ); - lines = usb_ReadData( dev ); - if( 0 == lines ) + scanning->dwLinesToProcess = usb_ReadData( dev ); + if( 0 == scanning->dwLinesToProcess ) return _E_DATAREAD; - - /* - * all settings done, so go ahead and read the data - */ - for( dw = 0; scanning->dwLinesUser; ) { - int wrap = 0; + return 0; +} - if( usb_IsEscPressed()) { - DBG( _DBG_INFO, "ReadImage() - Cancel detected...\n" ); - return 0; - } +/** + * + */ +static int usbDev_readLine( struct Plustek_Device *dev ) +{ + int wrap; + u_long cur, scaler; + pScanDef scanning = &dev->scanning; + pHWDef hw = &dev->usbDev.HwSetting; - if( !(scanning->dwFlag & SCANFLAG_SampleY)) { + scaler = 1; + if((hw->bReg_0x26 & _ONE_CH_COLOR) && + (scanning->sParam.bDataType == SCANDATATYPE_Color)) { + scaler = 3; + } - scanning->pfnProcess( dev ); + cur = scanning->dwLinesUser; - /* Adjust user buffer pointer */ - scanning->UserBuf.pb += scanning->lBufAdjust; - scanning->dwLinesUser--; - dw++; + /* we stay within this sample loop until one line has been processed for + * the user... + */ + while( cur == scanning->dwLinesUser ) { - } else { - scanning->wSumY += scanning->sParam.UserDpi.y; + if( usb_IsEscPressed()) { + DBG( _DBG_INFO, "readLine() - Cancel detected...\n" ); + return _E_ABORT; + } - if( scanning->wSumY >= scanning->sParam.PhyDpi.y ) { - scanning->wSumY -= scanning->sParam.PhyDpi.y; - - scanning->pfnProcess( dev ); - - /* Adjust user buffer pointer */ - scanning->UserBuf.pb += scanning->lBufAdjust; - scanning->dwLinesUser--; - dw++; - } - } + if( !(scanning->dwFlag & SCANFLAG_SampleY)) { - /* Adjust get buffer pointers */ - if( scanning->sParam.bDataType == SCANDATATYPE_Color ) { + scanning->pfnProcess( dev ); - scanning->Red.pb += (scanning->sParam.Size.dwPhyBytes * scaler); - if( scanning->Red.pb >= scanning->pbScanBufEnd ) { - scanning->Red.pb = scanning->pbScanBufBegin + - scanning->dwRedShift; - wrap = 1; - } + /* Adjust user buffer pointer */ + scanning->UserBuf.pb += scanning->lBufAdjust; + scanning->dwLinesUser--; - scanning->Green.pb += (scanning->sParam.Size.dwPhyBytes * scaler); - if( scanning->Green.pb >= scanning->pbScanBufEnd ) { - scanning->Green.pb = scanning->pbScanBufBegin + - scanning->dwGreenShift; - wrap = 1; - } + } else { - scanning->Blue.pb += (scanning->sParam.Size.dwPhyBytes * scaler); - if( scanning->Blue.pb >= scanning->pbScanBufEnd ) { - scanning->Blue.pb = scanning->pbScanBufBegin + - scanning->dwBlueShift; - wrap = 1; - } - } else { - scanning->Green.pb += scanning->sParam.Size.dwPhyBytes; - if( scanning->Green.pb >= scanning->pbScanBufEnd ) - scanning->Green.pb = scanning->pbScanBufBegin + - scanning->dwGreenShift; - } + scanning->wSumY += scanning->sParam.UserDpi.y; - /* - * on any wrap-around of the get pointers in one channel mode + if( scanning->wSumY >= scanning->sParam.PhyDpi.y ) { + scanning->wSumY -= scanning->sParam.PhyDpi.y; + + scanning->pfnProcess( dev ); + + /* Adjust user buffer pointer */ + scanning->UserBuf.pb += scanning->lBufAdjust; + scanning->dwLinesUser--; + } + } + + /* Adjust get buffer pointers */ + wrap = 0; + + if( scanning->sParam.bDataType == SCANDATATYPE_Color ) { + + scanning->Red.pb += (scanning->sParam.Size.dwPhyBytes * scaler); + if( scanning->Red.pb >= scanning->pbScanBufEnd ) { + scanning->Red.pb = scanning->pbScanBufBegin + + scanning->dwRedShift; + wrap = 1; + } + + scanning->Green.pb += (scanning->sParam.Size.dwPhyBytes * scaler); + if( scanning->Green.pb >= scanning->pbScanBufEnd ) { + scanning->Green.pb = scanning->pbScanBufBegin + + scanning->dwGreenShift; + wrap = 1; + } + + scanning->Blue.pb += (scanning->sParam.Size.dwPhyBytes * scaler); + if( scanning->Blue.pb >= scanning->pbScanBufEnd ) { + scanning->Blue.pb = scanning->pbScanBufBegin + + scanning->dwBlueShift; + wrap = 1; + } + } else { + scanning->Green.pb += scanning->sParam.Size.dwPhyBytes; + if( scanning->Green.pb >= scanning->pbScanBufEnd ) + scanning->Green.pb = scanning->pbScanBufBegin + + scanning->dwGreenShift; + } + + /* + * on any wrap-around of the get pointers in one channel mode * we have to reset them - */ - if( wrap ) { + */ + if( wrap ) { - if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + if( hw->bReg_0x26 & _ONE_CH_COLOR ) { - scanning->Red.pb = scanning->pbScanBufBegin; - scanning->Green.pb = scanning->pbScanBufBegin + - (scanning->sParam.Size.dwPhyBytes ); - scanning->Blue.pb = scanning->pbScanBufBegin + - (scanning->sParam.Size.dwPhyBytes )* 2UL; - } - } + scanning->Red.pb = scanning->pbScanBufBegin; + scanning->Green.pb = scanning->pbScanBufBegin + + (scanning->sParam.Size.dwPhyBytes ); + scanning->Blue.pb = scanning->pbScanBufBegin + + (scanning->sParam.Size.dwPhyBytes )* 2UL; + } + } - /* - * line processed, check if we have to get more... - */ - lines--; + /* + * line processed, check if we have to get more... + */ + scanning->dwLinesToProcess--; - if( 0 == lines ) { - - lines = usb_ReadData( dev ); - if(( 0 == lines ) && !usb_IsEscPressed()) - break; - } + if( 0 == scanning->dwLinesToProcess ) { + + scanning->dwLinesToProcess = usb_ReadData( dev ); + if( 0 == scanning->dwLinesToProcess ) { + + if( usb_IsEscPressed()) + return _E_ABORT; + } + } } - - DBG( _DBG_INFO, "We've got %lu bytes (%lu lines, needed: %lu bytes)\n", - (dw * scanning->dwBytesLine), dw, data_length ); - usb_ScanEnd( dev ); - return data_length; + /* after reaching the last line, home the sensor... */ + if( 0 == scanning->dwLinesUser ) + usb_ScanEnd( dev ); + + return 0; } /* END PLUSTEK-USB.C ........................................................*/ diff --git a/backend/plustek-usb.h b/backend/plustek-usb.h index 2fa40548b..4e1cd4660 100644 --- a/backend/plustek-usb.h +++ b/backend/plustek-usb.h @@ -239,17 +239,14 @@ typedef enum MODEL_KaoHsiung = 0, MODEL_HuaLien, MODEL_Tokyo600, - MODEL_NOPLUSTEK_600, /**< for 600 dpi models */ - MODEL_NOPLUSTEK_1200, /**< for 1200 dpi models */ - MODEL_EPSON, /**< for EPSON1250/1260 */ - MODEL_MUSTEK600, /**< for BearPaw 1200 */ - MODEL_MUSTEK1200, /**< for BearPaw 2400 */ - MODEL_HP, /**< for HP2x00 */ - MODEL_CANON650 , /**< for Canon N650U/656U */ - MODEL_CANON1220, /**< for Canon N1220U */ - MODEL_CANON670 , /**< for Canon N670U/676U */ - MODEL_CANON1240, /**< for Canon N1240U */ - MODEL_UMAX, /**< for UMAX 3400/3450 */ + MODEL_EPSON, /**< for EPSON1250/1260 */ + MODEL_MUSTEK600, /**< for BearPaw 1200 */ + MODEL_MUSTEK1200, /**< for BearPaw 2400 */ + MODEL_HP, /**< for HP2x00 */ + MODEL_CANON600 , /**< for CanoScan 600dpi models */ + MODEL_CANON1220, /**< for Canon N1220U */ + MODEL_CANON1240, /**< for Canon N1240U */ + MODEL_UMAX, /**< for UMAX 3400/3450 */ MODEL_LAST } eModelDef; @@ -541,6 +538,7 @@ typedef struct ScanDef AnyPtr UserBuf; /**< pointer to the user buffer */ u_long dwLinesUser; /**< Number of lines of user buffer */ u_long dwBytesLine; /**< Bytes per line of user buffer. */ + u_long dwLinesToProcess; /** Image processing routine according to the scan mode */ void (*pfnProcess)(struct Plustek_Device*); @@ -549,12 +547,12 @@ typedef struct ScanDef u_long dwLinesPerScanBufs; u_long dwNumberOfScanBufs; + u_long dwLinesScanBuf; u_char* pbScanBufBegin; u_char* pbScanBufEnd; u_char* pbGetDataBuf; u_long dwBytesScanBuf; - u_long dwLinesScanBuf; u_long dwLinesDiscard; u_long dwRedShift; @@ -584,9 +582,10 @@ typedef struct ScanDef */ typedef struct { - u_char pwm; - u_char pwm_duty; - + u_char pwm; /**< PWM */ + u_char pwm_duty; /**< PWM duty cycles */ + u_char scan_lines_per_line; /**< lines to scan to obtain 1 real line + will be used in 16bit color modes only */ } MDef, *pMDef; /** array used to get motor-settings and mclk-settings diff --git a/backend/plustek-usbhw.c b/backend/plustek-usbhw.c index 776b31c64..b0b17de0e 100644 --- a/backend/plustek-usbhw.c +++ b/backend/plustek-usbhw.c @@ -289,6 +289,17 @@ static SANE_Bool usb_ModuleMove( pPlustek_Device dev, a_bRegs[0x45] |= 0x10; + DBG( _DBG_INFO2,"MotorDPI=%u, MaxMoveSpeed=%.3f, " + "FFStepSize=%u, Steps=%lu\n", hw->wMotorDpi, + hw->dMaxMoveSpeed, wFastFeedStepSize, dwStep ); + DBG( _DBG_INFO2, "MOTOR: " + "PWM=0x%02x, PWM_DUTY=0x%02x 0x45=0x%02x " + "0x48=0x%02x, 0x49=0x%02x \n", + a_bRegs[0x56], a_bRegs[0x57], a_bRegs[0x45], + a_bRegs[0x48], a_bRegs[0x49] ); + + DBG( _DBG_INFO2,"MCLK_FFW = %u --> 0x%02x\n", mclk_div, (mclk_div-1)*2 ); + /* The setting for chassis moving is: * MCLK divider = 6, 8 bits/pixel, HDPI divider = 12, * no integration time adjustment and 1 channel grayscale diff --git a/backend/plustek-usbimg.c b/backend/plustek-usbimg.c index 0cc90bc5e..4d5548407 100644 --- a/backend/plustek-usbimg.c +++ b/backend/plustek-usbimg.c @@ -17,6 +17,7 @@ * - 0.44 - added CIS parts and dumpPic function * - 0.45 - added gray scaling functions for CIS devices * - fixed usb_GrayScale16 function + * - fixed a bug in usb_ColorScale16_2 function * . *
* This file is part of the SANE package. @@ -668,13 +669,13 @@ static void usb_ColorScale16_2( struct Plustek_Device *dev ) while((ddax < 0) && (dw > 0)) { - tmp = *((pHiLoDef)&scanning->Red.pw[dw]); + tmp = *((pHiLoDef)&scanning->Red.pw[dwBitsPut]); scanning->UserBuf.pw_rgb[dwPixels].Red = _HILO2WORD(tmp) >> Shift; - tmp = *((pHiLoDef)&scanning->Green.pw[dw]); + tmp = *((pHiLoDef)&scanning->Green.pw[dwBitsPut]); scanning->UserBuf.pw_rgb[dwPixels].Green = _HILO2WORD(tmp) >> Shift; - tmp = *((pHiLoDef)&scanning->Blue.pw[dw]); + tmp = *((pHiLoDef)&scanning->Blue.pw[dwBitsPut]); scanning->UserBuf.pw_rgb[dwPixels].Blue = _HILO2WORD(tmp) >> Shift; dwPixels = dwPixels + iNext; @@ -691,13 +692,13 @@ static void usb_ColorScale16_2( struct Plustek_Device *dev ) while((ddax < 0) && (dw > 0)) { - tmp = *((pHiLoDef)&scanning->Red.pw[dw]); + tmp = *((pHiLoDef)&scanning->Red.pw[dwBitsPut]); scanning->UserBuf.pw_rgb[dwPixels].Red = _HILO2WORD(tmp); - tmp = *((pHiLoDef)&scanning->Green.pw[dw]); + tmp = *((pHiLoDef)&scanning->Green.pw[dwBitsPut]); scanning->UserBuf.pw_rgb[dwPixels].Green = _HILO2WORD(tmp); - tmp = *((pHiLoDef)&scanning->Blue.pw[dw]); + tmp = *((pHiLoDef)&scanning->Blue.pw[dwBitsPut]); scanning->UserBuf.pw_rgb[dwPixels].Blue = _HILO2WORD(tmp); dwPixels = dwPixels + iNext; diff --git a/backend/plustek-usbscan.c b/backend/plustek-usbscan.c index cd2ae86a1..824f56a2b 100644 --- a/backend/plustek-usbscan.c +++ b/backend/plustek-usbscan.c @@ -523,7 +523,8 @@ static double usb_GetMCLKDivider( pPlustek_Device dev, pScanParam pParam ) m_bIntTimeAdjust = bMaxITA; } - if((hw->motorModel == MODEL_HP) && (sCaps->bCCD == kNECSLIM)) { + if(((hw->motorModel == MODEL_HP) && (sCaps->bCCD == kNECSLIM))/* || + ( a_bRegs[0x26] & _ONE_CH_COLOR )*/) { bMaxITA = (u_char)floor((m_dMCLKDivider + 1) / 2.0); @@ -742,6 +743,22 @@ static void usb_GetMotorParam( pPlustek_Device dev, pScanParam pParam ) a_bRegs[0x56] = md[idx].pwm; a_bRegs[0x57] = md[idx].pwm_duty; + a_bRegs[0x43] = 0; + a_bRegs[0x44] = 0; + + if( md[idx].scan_lines_per_line > 1 ) { + + if((pParam->bBitDepth > 8) && + (pParam->bDataType == SCANDATATYPE_Color)) { + + a_bRegs[0x43] = 0xff; + a_bRegs[0x44] = md[idx].scan_lines_per_line; + + DBG( _DBG_INFO, "* Line Skipping : 0x43=0x%02x, 0x44=0x%02x\n", + a_bRegs[0x43], a_bRegs[0x44] ); + } + } + } else { if( sCaps->OpticDpi.x == 1200 ) { @@ -1029,6 +1046,12 @@ static SANE_Bool usb_SetScanParameters( pPlustek_Device dev, pScanParam pParam ) m_wFastFeedStepSize = (u_short)(dwCrystalFrequency / (m_dMCLKDivider * 8 * m_bCM * hw->dMaxMoveSpeed * 4 * hw->wMotorDpi)); + /* CIS special ;-) */ + if((hw->bReg_0x26 & _ONE_CH_COLOR) && (m_bCM == 1)) { + DBG( _DBG_INFO2, "* CIS FFStep-Speedup\n" ); + m_wFastFeedStepSize /= 3; + } + if( m_bIntTimeAdjust != 0 ) m_wFastFeedStepSize /= m_bIntTimeAdjust; diff --git a/backend/plustek-usbshading.c b/backend/plustek-usbshading.c index ab966a118..8f277799c 100644 --- a/backend/plustek-usbshading.c +++ b/backend/plustek-usbshading.c @@ -494,7 +494,8 @@ static u_char usb_GetNewGain( u_short wMax ) } /** limit and set register given by address - * + * @param gain - + * @param reg - */ static void setAdjGain( int gain, u_char *reg ) { @@ -510,6 +511,10 @@ static void setAdjGain( int gain, u_char *reg ) /** * @param channel - 0 = red, 1 = green, 2 = blue * @param max - + * @param ideal - + * @param l_on - + * @param l_off - + * @return */ static SANE_Bool adjLampSetting( int channel, u_long max, u_long ideal, u_short l_on, u_short *l_off ) @@ -696,12 +701,13 @@ TOGAIN: if( m_ScanParam.bDataType == SCANDATATYPE_Color ) { - RGBUShortDef rgb; + RGBUShortDef max_rgb, min_rgb, tmp; u_long dwR, dwG, dwB; u_long dwDiv = 10; u_long dwLoop1 = m_ScanParam.Size.dwPhyPixels / dwDiv, dwLoop2; - rgb.Red = rgb.Green = rgb.Blue = 0; + max_rgb.Red = max_rgb.Green = max_rgb.Blue = 0; + min_rgb.Red = min_rgb.Green = min_rgb.Blue = 0xffff; /* find out the max pixel value for R, G, B */ for( dw = 0; dwLoop1; dwLoop1-- ) { @@ -725,23 +731,45 @@ TOGAIN: dwG = dwG / dwDiv; dwB = dwB / dwDiv; - if(rgb.Red < dwR) - rgb.Red = dwR; - if(rgb.Green < dwG) - rgb.Green = dwG; - if(rgb.Blue < dwB) - rgb.Blue = dwB; + if(max_rgb.Red < dwR) + max_rgb.Red = dwR; + if(max_rgb.Green < dwG) + max_rgb.Green = dwG; + if(max_rgb.Blue < dwB) + max_rgb.Blue = dwB; + + if(min_rgb.Red > dwR) + min_rgb.Red = dwR; + if(min_rgb.Green > dwG) + min_rgb.Green = dwG; + if(min_rgb.Blue > dwB) + min_rgb.Blue = dwB; } DBG(_DBG_INFO2, "MAX(R,G,B)= 0x%04x(%u), 0x%04x(%u), 0x%04x(%u)\n", - rgb.Red, rgb.Red, rgb.Green, rgb.Green, rgb.Blue, rgb.Blue ); + max_rgb.Red, max_rgb.Red, max_rgb.Green, + max_rgb.Green, max_rgb.Blue, max_rgb.Blue ); + DBG(_DBG_INFO2, "MIN(R,G,B)= 0x%04x(%u), 0x%04x(%u), 0x%04x(%u)\n", + min_rgb.Red, min_rgb.Red, min_rgb.Green, + min_rgb.Green, min_rgb.Blue, min_rgb.Blue ); + + /* on CIS scanner, we use the min value, on CCD the max value + * for adjusting the gain + */ + tmp = max_rgb; + if( hw->bReg_0x26 & _ONE_CH_COLOR ) + tmp = min_rgb; + + DBG(_DBG_INFO2, "CUR(R,G,B)= 0x%04x(%u), 0x%04x(%u), 0x%04x(%u)\n", + tmp.Red, tmp.Red, tmp.Green, tmp.Green, tmp.Blue, tmp.Blue); m_dwIdealGain = IDEAL_GainNormal; + m_dwIdealGain = 0xff00; /* min(min(rgb.wRed, rgb.wGreen), rgb.wBlue) */ - a_bRegs[0x3b] = usb_GetNewGain( rgb.Red ); - a_bRegs[0x3c] = usb_GetNewGain( rgb.Green ); - a_bRegs[0x3d] = usb_GetNewGain( rgb.Blue ); + a_bRegs[0x3b] = usb_GetNewGain( tmp.Red ); + a_bRegs[0x3c] = usb_GetNewGain( tmp.Green ); + a_bRegs[0x3d] = usb_GetNewGain( tmp.Blue ); if( !_IS_PLUSTEKMOTOR(hw->motorModel)) { @@ -750,17 +778,19 @@ TOGAIN: /* on CIS devices, we can control the lamp off settings */ if( hw->bReg_0x26 & _ONE_CH_COLOR ) { - if( adjLampSetting( CHANNEL_red, rgb.Red, m_dwIdealGain, + m_dwIdealGain = IDEAL_GainNormal; + + if( adjLampSetting( CHANNEL_red, min_rgb.Red, m_dwIdealGain, hw->red_lamp_on, &hw->red_lamp_off )) { adj = SANE_TRUE; } - if( adjLampSetting( CHANNEL_green, rgb.Green, m_dwIdealGain, + if( adjLampSetting( CHANNEL_green, min_rgb.Green, m_dwIdealGain, hw->green_lamp_on, &hw->green_lamp_off )) { adj = SANE_TRUE; } - if( adjLampSetting( CHANNEL_blue, rgb.Blue, m_dwIdealGain, + if( adjLampSetting( CHANNEL_blue, min_rgb.Blue, m_dwIdealGain, hw->blue_lamp_on, &hw->blue_lamp_off)){ adj = SANE_TRUE; } @@ -844,15 +874,25 @@ TOGAIN: } } else { - u_short w = 0; + + u_short w_max = 0, w_min = 0xffff, tmp; for( dw = 0; dw < m_ScanParam.Size.dwPhyPixels; dw++ ) { - if( w < ((u_short*)pScanBuffer)[dw]) - w = ((u_short*)pScanBuffer)[dw]; + if( w_max < ((u_short*)pScanBuffer)[dw]) + w_max = ((u_short*)pScanBuffer)[dw]; + if( w_min > ((u_short*)pScanBuffer)[dw]) + w_min = ((u_short*)pScanBuffer)[dw]; } - a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = usb_GetNewGain(w); - DBG(_DBG_INFO2, "MAX(G)= 0x%04x(%u)\n", w, w ); + tmp = w_max; + if( hw->bReg_0x26 & _ONE_CH_COLOR ) + tmp = w_min; + + a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = usb_GetNewGain(tmp); + + DBG(_DBG_INFO2, "MAX(G)= 0x%04x(%u)\n", w_max, w_max ); + DBG(_DBG_INFO2, "MIN(G)= 0x%04x(%u)\n", w_min, w_min ); + DBG(_DBG_INFO2, "CUR(G)= 0x%04x(%u)\n", tmp, tmp ); m_dwIdealGain = IDEAL_GainNormal; @@ -863,7 +903,7 @@ TOGAIN: /* on CIS devices, we can control the lamp off settings */ if( hw->bReg_0x26 & _ONE_CH_COLOR ) { - if( adjLampSetting( CHANNEL_green, w, m_dwIdealGain, + if( adjLampSetting( CHANNEL_green, w_min, m_dwIdealGain, hw->green_lamp_on, &hw->green_lamp_off )) { adj = SANE_TRUE; } @@ -905,6 +945,7 @@ TOGAIN: DBG( _DBG_INFO2, "REG[0x3c] = %u\n", a_bRegs[0x3c] ); DBG( _DBG_INFO2, "REG[0x3d] = %u\n", a_bRegs[0x3d] ); + /* adjust gain here if the user has set some values >= 0 */ setAdjGain( dev->adj.rgain, &a_bRegs[0x3b] ); setAdjGain( dev->adj.ggain, &a_bRegs[0x3c] ); setAdjGain( dev->adj.bgain, &a_bRegs[0x3d] ); @@ -927,42 +968,51 @@ TOGAIN: } /** usb_GetNewOffset - * + * @param pdwSum - + * @param pdwDiff - + * @param pcOffset - + * @param pIdeal - + * @param channel - + * @param cAdjust - */ static void usb_GetNewOffset( u_long *pdwSum, u_long *pdwDiff, signed char *pcOffset, u_char *pIdeal, - u_long dw, signed char cAdjust ) + u_long channel, signed char cAdjust ) { /* IDEAL_Offset is currently set to 0x1000 = 4096 */ u_long dwIdealOffset = IDEAL_Offset; - if( pdwSum[dw] > dwIdealOffset ) { + /* for CIS to 2048 */ + if( a_bRegs[0x26] & _ONE_CH_COLOR ) + dwIdealOffset = 0x800; + + if( pdwSum[channel] > dwIdealOffset ) { /* Over ideal value */ - pdwSum[dw] -= dwIdealOffset; - if( pdwSum[dw] < pdwDiff[dw] ) { + pdwSum[channel] -= dwIdealOffset; + if( pdwSum[channel] < pdwDiff[channel] ) { /* New offset is better than old one */ - pdwDiff[dw] = pdwSum[dw]; - pIdeal[dw] = a_bRegs[0x38 + dw]; + pdwDiff[channel] = pdwSum[channel]; + pIdeal[channel] = a_bRegs[0x38 + channel]; } - pcOffset[dw] -= cAdjust; + pcOffset[channel] -= cAdjust; } else { /* Below than ideal value */ - pdwSum[dw] = dwIdealOffset - pdwSum [dw]; - if( pdwSum[dw] < pdwDiff[dw] ) { + pdwSum[channel] = dwIdealOffset - pdwSum [channel]; + if( pdwSum[channel] < pdwDiff[channel] ) { /* New offset is better than old one */ - pdwDiff[dw] = pdwSum[dw]; - pIdeal[dw] = a_bRegs[0x38 + dw]; + pdwDiff[channel] = pdwSum[channel]; + pIdeal[channel] = a_bRegs[0x38 + channel]; } - pcOffset[dw] += cAdjust; + pcOffset[channel] += cAdjust; } - if( pcOffset[dw] >= 0 ) - a_bRegs[0x38 + dw] = pcOffset[dw]; + if( pcOffset[channel] >= 0 ) + a_bRegs[0x38 + channel] = pcOffset[channel]; else - a_bRegs[0x38 + dw] = (u_char)(32 - pcOffset[dw]); + a_bRegs[0x38 + channel] = (u_char)(32 - pcOffset[channel]); } /** usb_AdjustOffset @@ -1017,6 +1067,27 @@ static SANE_Bool usb_AdjustOffset( pPlustek_Device dev ) a_bRegs[0x38] = a_bRegs [0x39] = a_bRegs [0x3a] = 0; + if( hw->bReg_0x26 & _ONE_CH_COLOR ) { + /* + * if we have dark shading strip, there's no need to switch + * the lamp off + */ + if( dev->usbDev.pSource->DarkShadOrgY >= 0 ) { + + usb_ModuleToHome( dev, SANE_TRUE ); + usb_ModuleMove ( dev, MOVE_Forward, + (u_long)dev->usbDev.pSource->DarkShadOrgY ); + + a_bRegs[0x45] &= ~0x10; + + } else { + + /* switch lamp off to read dark data... */ + a_bRegs[0x29] = 0; + usb_switchLamp( dev, SANE_FALSE ); + } + } + if( 0 == dwPixels ) { DBG( _DBG_ERROR, "OpticBlackEnd = OpticBlackStart!!!\n" ); return SANE_FALSE; @@ -1034,11 +1105,6 @@ static SANE_Bool usb_AdjustOffset( pPlustek_Device dev ) if( m_ScanParam.bDataType == SCANDATATYPE_Color ) bytes2get *= 3; - - /* switch off the lamps on CIS based scanners */ - a_bRegs[0x29] = 0; - usb_switchLamp( dev, SANE_FALSE ); - usbio_WriteReg( dev->fd, 0x29, a_bRegs[0x29]); } DBG( _DBG_INFO2, "S.dwPixels = %lu\n", m_ScanParam.Size.dwPixels ); @@ -1069,6 +1135,7 @@ static SANE_Bool usb_AdjustOffset( pPlustek_Device dev ) dwSum[0] = dwSum[1] = dwSum[2] = 0; for (dw = 0; dw < dwPixels; dw++) { + dwSum[0] += (u_long)_HILO2WORD(((pColorWordDef)pScanBuffer)[dw].HiLo[0]); dwSum[1] += (u_long)_HILO2WORD(((pColorWordDef)pScanBuffer)[dw].HiLo[1]); dwSum[2] += (u_long)_HILO2WORD(((pColorWordDef)pScanBuffer)[dw].HiLo[2]); @@ -1102,6 +1169,11 @@ static SANE_Bool usb_AdjustOffset( pPlustek_Device dev ) dwSum [0] /= dwPixels; usb_GetNewOffset( dwSum, dwDiff, cOffset, bExpect, 0, cAdjust ); a_bRegs[0x3a] = a_bRegs[0x39] = a_bRegs[0x38]; + + DBG( _DBG_INFO2, "Sum = %lu, ave = %lu\n", + dwSum[0], dwSum[0] /dwPixels ); + + DBG( _DBG_INFO2, "Expect = %u\n", bExpect[0] ); } _UIO(sanei_lm983x_write(dev->fd, 0x38, &a_bRegs[0x38], 3, SANE_TRUE)); @@ -1113,6 +1185,7 @@ static SANE_Bool usb_AdjustOffset( pPlustek_Device dev ) a_bRegs[0x39] = bExpect[1]; a_bRegs[0x3a] = bExpect[2]; } else { + a_bRegs[0x38] = a_bRegs[0x39] = a_bRegs[0x3a] = bExpect[0]; } @@ -1123,9 +1196,12 @@ static SANE_Bool usb_AdjustOffset( pPlustek_Device dev ) /* switch it on again on CIS based scanners */ if( hw->bReg_0x26 & _ONE_CH_COLOR ) { - a_bRegs[0x29] = hw->bReg_0x29; - usb_switchLamp( dev, SANE_TRUE ); - usbio_WriteReg( dev->fd, 0x29, a_bRegs[0x29]); + + if( dev->usbDev.pSource->DarkShadOrgY < 0 ) { + a_bRegs[0x29] = hw->bReg_0x29; + usb_switchLamp( dev, SANE_TRUE ); + usbio_WriteReg( dev->fd, 0x29, a_bRegs[0x29]); + } } return SANE_TRUE; @@ -1236,13 +1312,17 @@ static SANE_Bool usb_AdjustDarkShading( pPlustek_Device dev ) if( scaps->workaroundFlag & _WAF_SKIP_FINE ) return SANE_TRUE; + DBG( _DBG_INFO2, "usb_AdjustDarkShading()\n" ); + DBG( _DBG_INFO2, "MCLK = %f (scanparam-MCLK=%f)\n", + dMCLK, scanning->sParam.dMCLK ); + m_ScanParam = scanning->sParam; m_ScanParam.Origin.y = 0; m_ScanParam.UserDpi.y = scaps->OpticDpi.y; m_ScanParam.Size.dwLines = 1; /* for gain */ m_ScanParam.bBitDepth = 16; m_ScanParam.bCalibration = PARAM_DarkShading; - m_ScanParam.dMCLK = dMCLK; + m_ScanParam.dMCLK = dMCLK; if( _LM9831 == hw->chip ) { @@ -1781,7 +1861,7 @@ static SANE_Bool usb_AdjustWhiteShading( pPlustek_Device dev ) } if( hw->bReg_0x26 & _ONE_CH_COLOR ) { -#if 0 +#if 1 u_short *dest, *src; u_long dww; @@ -2020,7 +2100,7 @@ static int usb_DoCalibration( pPlustek_Device dev ) #endif DBG( _DBG_INFO, "--> BYPASS\n" ); - a_bRegs[0x38] = a_bRegs[0x39] = a_bRegs[0x3a] = 1; + a_bRegs[0x38] = a_bRegs[0x39] = a_bRegs[0x3a] = 0; a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = 1; setAdjGain( dev->adj.rgain, &a_bRegs[0x3b] ); @@ -2192,10 +2272,9 @@ static int usb_DoCalibration( pPlustek_Device dev ) DBG( _DBG_INFO, "No Plustek model: %udpi\n", scanning->sParam.PhyDpi.x ); usb_SetMCLK( dev, &scanning->sParam ); -/* if( a_bRegs[0x26] & _ONE_CH_COLOR ) - */ usb_SetMCLK( dev, &m_ScanParam ); } else if( dev->usbDev.Caps.OpticDpi.x == 600 ) { + DBG( _DBG_INFO, "Default Shading (600dpi)\n" ); if( dev->usbDev.Caps.bCCD == kSONY548 ) { @@ -2318,18 +2397,23 @@ static int usb_DoCalibration( pPlustek_Device dev ) m_dwIdealGain = IDEAL_GainNormal; DBG( _DBG_INFO, "Settings done, so start...\n" ); + DBG( _DBG_INFO2, "###### ADJUST GAIN (COARSE)#######\n" ); + if( !usb_AdjustGain(dev, 0)) { DBG( _DBG_ERROR, "Coarse Calibration failed!!!\n" ); return _E_INTERNAL; } + DBG( _DBG_INFO2, "###### ADJUST OFFSET (COARSE) ####\n" ); if( !usb_AdjustOffset(dev)) { DBG( _DBG_ERROR, "Coarse Calibration failed!!!\n" ); return _E_INTERNAL; } + DBG( _DBG_INFO2, "###### ADJUST DARK (FINE) ########\n" ); if( !usb_AdjustDarkShading(dev)) { DBG( _DBG_ERROR, "Fine Calibration failed!!!\n" ); return _E_INTERNAL; } + DBG( _DBG_INFO2, "###### ADJUST WHITE (FINE) #######\n" ); if( !usb_AdjustWhiteShading(dev)) { DBG( _DBG_ERROR, "Fine Calibration failed!!!\n" ); return _E_INTERNAL; diff --git a/backend/plustek.c b/backend/plustek.c index 59c972081..4ac3380c7 100644 --- a/backend/plustek.c +++ b/backend/plustek.c @@ -56,6 +56,7 @@ * - fixed a bug, that stops our lamp timer * - 0.45 - added additional flags * - added WIFSIGNALED to check result of child termination + * - changed readImage interface for USB devices *. *
* This file is part of the SANE package. @@ -129,7 +130,7 @@ #include "sane/sanei.h" #include "sane/saneopts.h" -#define BACKEND_VERSION "0.45-1" +#define BACKEND_VERSION "0.45-3" #define BACKEND_NAME plustek #include "sane/sanei_backend.h" #include "sane/sanei_config.h" @@ -489,6 +490,7 @@ static RETSIGTYPE sigalarm_handler( int signal ) */ static int reader_process( Plustek_Scanner *scanner, int pipe_fd ) { + int line; unsigned long status; unsigned long data_length; struct SIGACTION act; @@ -521,8 +523,32 @@ static int reader_process( Plustek_Scanner *scanner, int pipe_fd ) } /* here we read all data from the driver... */ - status = (unsigned long)scanner->hw->readImage( scanner->hw, + if( scanner->hw->readImage ) { + + status = (unsigned long)scanner->hw->readImage( scanner->hw, scanner->buf, data_length); + } else { + + unsigned char *buf = scanner->buf; + + + status = scanner->hw->prepare( scanner->hw, buf ); + + if( 0 == status ) { + + for( line = 0; line < scanner->params.lines; line++ ) { + + status = scanner->hw->readLine( scanner->hw ); + if((int)status < 0 ) { + break; + } + + write( pipe_fd, buf, scanner->params.bytes_per_line ); + + buf += scanner->params.bytes_per_line; + } + } + } /* on error, there's no need to clean up, as this is done by the parent */ if((int)status < 0 ) { @@ -538,9 +564,10 @@ static int reader_process( Plustek_Scanner *scanner, int pipe_fd ) } /* send to parent */ - DBG( _DBG_PROC, "sending %lu bytes to parent\n", status ); - - write( pipe_fd, scanner->buf, status ); + if( scanner->hw->readImage ) { + DBG( _DBG_PROC, "sending %lu bytes to parent\n", status ); + write( pipe_fd, scanner->buf, status ); + } pipe_fd = -1; @@ -1173,6 +1200,8 @@ static SANE_Status attach( const char *dev_name, pCnfDef cnf, dev->setMap = ppDev_setMap; dev->readImage = ppDev_readImage; dev->shutdown = NULL; + dev->readLine = NULL; + dev->prepare = NULL; } else { @@ -1189,7 +1218,9 @@ static SANE_Status attach( const char *dev_name, pCnfDef cnf, dev->startScan = usbDev_startScan; dev->stopScan = usbDev_stopScan; dev->setMap = usbDev_setMap; - dev->readImage = usbDev_readImage; + dev->readImage = NULL; + dev->readLine = usbDev_readLine; + dev->prepare = usbDev_Prepare; dev->shutdown = usbDev_shutdown; strncpy( dev->usbId, cnf->usbId, _MAX_ID_LEN ); @@ -1263,6 +1294,7 @@ static SANE_Status attach( const char *dev_name, pCnfDef cnf, dev->sane.model = ModelStr[0]; } + DBG( _DBG_INFO, "Vendor : %s\n", dev->sane.vendor ); DBG( _DBG_INFO, "Model : %s\n", dev->sane.model ); DBG( _DBG_INFO, "Asic : 0x%02x\n", dev->caps.AsicID ); DBG( _DBG_INFO, "Flags : 0x%08lx\n", dev->caps.dwFlag ); diff --git a/backend/plustek.conf b/backend/plustek.conf index d3ebf3b44..c77f337aa 100644 --- a/backend/plustek.conf +++ b/backend/plustek.conf @@ -100,7 +100,7 @@ option skipCalibration 0 # for skipping entire fine calibration step # coarse calibration is done -option skipFineCalibration 0 +option skipFine 0 # discard the result of the fine white calibration option skipFineWhite 0 diff --git a/backend/plustek.h b/backend/plustek.h index 828fd826e..cb63ad429 100644 --- a/backend/plustek.h +++ b/backend/plustek.h @@ -39,7 +39,7 @@ * - added _MAX_ID_LEN * - 0.43 - no changes * - 0.44 - added flag initialized - * - 0.45 - no changes + * - 0.45 - added readLine function * . *
* This file is part of the SANE package. @@ -203,6 +203,9 @@ typedef struct Plustek_Device int (*stopScan) ( struct Plustek_Device*, int* ); int (*readImage) ( struct Plustek_Device*, SANE_Byte*, unsigned long ); + int (*prepare) ( struct Plustek_Device*, SANE_Byte* ); + int (*readLine) ( struct Plustek_Device* ); + } Plustek_Device, *pPlustek_Device; typedef union diff --git a/doc/descriptions/plustek.desc b/doc/descriptions/plustek.desc index 478ff67ea..cccc03471 100644 --- a/doc/descriptions/plustek.desc +++ b/doc/descriptions/plustek.desc @@ -76,8 +76,8 @@ :model "OpticPro AI3" :interface "Parport (SPP, EPP)" -:status :stable -:comment "use driver-switch mov=5" +:status :beta +:comment "use driver-switch mov=5, poor picture quality" :model "OpticPro P8" :interface "Parport" @@ -271,26 +271,26 @@ :model "CanoScan N1220U" :interface "USB" -:status :stable +:status :beta :comment "Poor color picture quality" :model "CanoScan N670U/N676U" :interface "USB" -:status :stable +:status :beta :comment "Poor color picture quality" :model "CanoScan N1240U" :interface "USB" -:status :stable +:status :beta :comment "Poor color picture quality" -:model "CanoScan LIDE20" +:model "CanoScan LiDE20" :interface "USB" -:status :stable +:status :beta :comment "Poor color picture quality" -:model "CanoScan LIDE30" +:model "CanoScan LiDE30" :interface "USB" -:status :stable +:status :beta :comment "Poor color picture quality" diff --git a/doc/plustek/Plustek-USB-TODO.txt b/doc/plustek/Plustek-USB-TODO.txt index 60d8422fe..afce0f2d9 100644 --- a/doc/plustek/Plustek-USB-TODO.txt +++ b/doc/plustek/Plustek-USB-TODO.txt @@ -1,10 +1,11 @@ -Plustek-USB-TODO.txt (2003-01-11) Gerhard Jäger +Plustek-USB-TODO.txt (2003-01-21) Gerhard Jäger ==================================================================== TODO (in general): - more documentation/comments on the different functions - Move documents to its correct SANE place - improve calibration + - copy picture line by line to backend KNOWN BUGS/Limitations: @@ -14,8 +15,6 @@ Canon fine calibration does not work none Canon 650 color modes >=600 dpi too dark change gamma settings Canon 1220 image quality not very good none Canon 1240 gray mode too bright none -all but Plustek improve motor settings for 42bit none - modes ********************************* DONE *************************************** diff --git a/doc/plustek/Plustek-USB.txt b/doc/plustek/Plustek-USB.txt index 0a4a9aa20..e4fe5d63a 100644 --- a/doc/plustek/Plustek-USB.txt +++ b/doc/plustek/Plustek-USB.txt @@ -181,6 +181,12 @@ and fill in the appropriate vendor and product id (see there for examples) This is it... +Autoloading scanner.o +--------------------- + +boot.local + + Debugging your USB scanner (written by Kev Green) -------------------------------------------------