improved bulk read data

merge-requests/1/head
Stphane Voltz 2010-05-09 09:47:17 +02:00
rodzic e726900b56
commit 4fd418daef
1 zmienionych plików z 143 dodań i 103 usunięć

Wyświetl plik

@ -149,18 +149,20 @@ gl847_bulk_write_register (Genesys_Device * dev,
return status; return status;
} }
/** /** @brief read scanned data
* Read bulk data (e.g. scanned data) * We never read more data than valid words advertised
* the we split read in 0xeff0 maximum blocks. This read is done in 2
* parts if not multple of 512
* first read is rounded to a multiple of 512 bytes, last read fetches the * first read is rounded to a multiple of 512 bytes, last read fetches the
* remainder XXX STEF XXX check rounded is ASIC work not software * remainder.
* addr is always 0x10000000 * addr is always 0x10000000 with the memory layout setup
*/ */
static SANE_Status static SANE_Status
gl847_bulk_read_data (Genesys_Device * dev, uint8_t addr, gl847_bulk_read_data (Genesys_Device * dev, uint8_t addr,
uint8_t * data, size_t len) uint8_t * data, size_t len)
{ {
SANE_Status status; SANE_Status status;
size_t size, target; size_t size, target, read;
uint8_t outdata[8], value; uint8_t outdata[8], value;
uint32_t words; uint32_t words;
@ -169,11 +171,6 @@ gl847_bulk_read_data (Genesys_Device * dev, uint8_t addr,
if (len == 0) if (len == 0)
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
if (len > 0xeff0)
target = 0xeff0;
else
target = len;
/* we don't read more data than valid words avertised */ /* we don't read more data than valid words avertised */
RIE (sanei_genesys_read_register (dev, 0x42, &value)); RIE (sanei_genesys_read_register (dev, 0x42, &value));
words = (value & 0x03); words = (value & 0x03);
@ -184,45 +181,62 @@ gl847_bulk_read_data (Genesys_Device * dev, uint8_t addr,
RIE (sanei_genesys_read_register (dev, 0x45, &value)); RIE (sanei_genesys_read_register (dev, 0x45, &value));
words = words * 256 + value; words = words * 256 + value;
if (target > 4 * words) if (len > 4 * words)
target = 4 * words;
/* XXX STEF XXX do address handling cleaner */
outdata[0] = 0;
outdata[1] = 0;
outdata[2] = 0;
outdata[3] = 0x10;
outdata[4] = (target & 0xff);
outdata[5] = ((target >> 8) & 0xff);
outdata[6] = ((target >> 16) & 0xff);
outdata[7] = ((target >> 24) & 0xff);
status =
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_BUFFER,
VALUE_BUFFER, INDEX, sizeof (outdata), outdata);
if (status != SANE_STATUS_GOOD)
{ {
DBG (DBG_error, "%s failed while writing command: %s\n", __FUNCTION__, target = 4 * words;
sane_strstatus (status)); }
return status; else
{
target = len;
} }
size = target; /* loop until computed data size is read */
while (target) while (target)
{ {
/* XXX STEF XXX */ if (target > 0xeff0)
if (size >= 512)
{ {
size /= 512; size = 0xeff0;
size *= 512; }
else
{
size = target;
}
/* hard coded 0x10000000 addr */
outdata[0] = 0;
outdata[1] = 0;
outdata[2] = 0;
outdata[3] = 0x10;
/* data size to transfer */
outdata[4] = (size & 0xff);
outdata[5] = ((size >> 8) & 0xff);
outdata[6] = ((size >> 16) & 0xff);
outdata[7] = ((size >> 24) & 0xff);
status =
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_BUFFER,
VALUE_BUFFER, INDEX, sizeof (outdata),
outdata);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "%s failed while writing command: %s\n",
__FUNCTION__, sane_strstatus (status));
return status;
}
/* blocks must be multiple of 512 but not last block */
read = size;
if (read >= 512)
{
read /= 512;
read *= 512;
} }
DBG (DBG_io2, DBG (DBG_io2,
"gl847_bulk_read_data: trying to read %lu bytes of data\n", "gl847_bulk_read_data: trying to read %lu bytes of data\n",
(u_long) size); (u_long) read);
status = sanei_usb_read_bulk (dev->dn, data, &read);
status = sanei_usb_read_bulk (dev->dn, data, &size);
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
{ {
DBG (DBG_error, DBG (DBG_error,
@ -231,6 +245,23 @@ gl847_bulk_read_data (Genesys_Device * dev, uint8_t addr,
return status; return status;
} }
/* read less than 512 bytes remainder */
if (read < size)
{
read = size - read;
DBG (DBG_io2,
"gl847_bulk_read_data: trying to read %lu bytes of data\n",
(u_long) read);
status = sanei_usb_read_bulk (dev->dn, data, &read);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"gl847_bulk_read_data failed while reading bulk data: %s\n",
sane_strstatus (status));
return status;
}
}
DBG (DBG_io2, "%s: read %lu bytes, %lu remaining\n", __FUNCTION__, DBG (DBG_io2, "%s: read %lu bytes, %lu remaining\n", __FUNCTION__,
(u_long) size, (u_long) (target - size)); (u_long) size, (u_long) (target - size));
@ -581,12 +612,12 @@ gl847_send_slope_table (Genesys_Device * dev, int table_nr,
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
{ {
DBG (DBG_error, DBG (DBG_error,
"%s: write to AHB failed writing slope table %d (%s)\n", __FUNCTION__, "%s: write to AHB failed writing slope table %d (%s)\n",
table_nr, sane_strstatus (status)); __FUNCTION__, table_nr, sane_strstatus (status));
} }
free (table); free (table);
DBG (DBG_proc, "%s: completed\n",__FUNCTION__); DBG (DBG_proc, "%s: completed\n", __FUNCTION__);
return status; return status;
} }
@ -705,7 +736,8 @@ gl847_set_fe (Genesys_Device * dev, uint8_t set)
* *
*/ */
static SANE_Status static SANE_Status
gl847_init_motor_regs_off (Genesys_Device * dev, Genesys_Register_Set * reg, gl847_init_motor_regs_off (Genesys_Device * dev,
Genesys_Register_Set * reg,
unsigned int scan_lines) unsigned int scan_lines)
{ {
unsigned int feedl; unsigned int feedl;
@ -828,12 +860,9 @@ gl847_init_motor_regs (Genesys_Device * dev, Genesys_Register_Set * reg, unsigne
{ {
/* FEED and GO_HOME can use fastest slopes available */ /* FEED and GO_HOME can use fastest slopes available */
fast_slope_steps = 256; fast_slope_steps = 256;
fast_exposure = sanei_genesys_exposure_time2 (dev, fast_exposure = sanei_genesys_exposure_time2 (dev, dev->motor.base_ydpi / 4, 0, /*step_type */
dev->motor.base_ydpi / 4,
0, /*step_type */
0, /*last used pixel */ 0, /*last used pixel */
0, 0, 0);
0);
DBG (DBG_info, "gl847_init_motor_regs : fast_exposure=%d pixels\n", DBG (DBG_info, "gl847_init_motor_regs : fast_exposure=%d pixels\n",
fast_exposure); fast_exposure);
@ -852,8 +881,8 @@ gl847_init_motor_regs (Genesys_Device * dev, Genesys_Register_Set * reg, unsigne
fast_slope_steps, fast_slope_steps,
0, 0,
fast_exposure, fast_exposure,
dev->motor.base_ydpi / 4, dev->motor.base_ydpi /
&fast_slope_steps, 4, &fast_slope_steps,
&fast_exposure, 0); &fast_exposure, 0);
feedl = feed_steps - fast_slope_steps * 2; feedl = feed_steps - fast_slope_steps * 2;
@ -1049,11 +1078,9 @@ gl847_init_motor_regs_scan (Genesys_Device * dev, Genesys_Register_Set * reg, un
scan_step_type, scan_step_type,
scan_lines, scan_dummy, feed_steps, scan_power_mode, flags); scan_lines, scan_dummy, feed_steps, scan_power_mode, flags);
fast_exposure = sanei_genesys_exposure_time2 (dev, dev->motor.base_ydpi / 4, fast_exposure =
0, sanei_genesys_exposure_time2 (dev, dev->motor.base_ydpi / 4, 0, 0, 0,
0, scan_power_mode);
0,
scan_power_mode);
DBG (DBG_info, "gl847_init_motor_regs_scan : fast_exposure=%d pixels\n", DBG (DBG_info, "gl847_init_motor_regs_scan : fast_exposure=%d pixels\n",
fast_exposure); fast_exposure);
@ -1146,6 +1173,9 @@ gl847_init_motor_regs_scan (Genesys_Device * dev, Genesys_Register_Set * reg, un
use_fast_fed = fast_time < slow_time; use_fast_fed = fast_time < slow_time;
} }
/* XXX STEF XXX */
use_fast_fed = 0;
if (use_fast_fed) if (use_fast_fed)
feedl = feed_steps - fast_slope_steps * 2 - feedl = feed_steps - fast_slope_steps * 2 -
(slow_slope_steps >> scan_step_type); (slow_slope_steps >> scan_step_type);
@ -1194,7 +1224,7 @@ gl847_init_motor_regs_scan (Genesys_Device * dev, Genesys_Register_Set * reg, un
RIE (sanei_genesys_read_register (dev, REG6C, &effective)); RIE (sanei_genesys_read_register (dev, REG6C, &effective));
if (scan_yres >= dev->sensor.optical_res / 2) if (scan_yres >= dev->sensor.optical_res / 2)
{ {
val = effective & ~REG6C_GPIO14; val = effective & ~REG6C_GPIO13;
} }
RIE (sanei_genesys_write_register (dev, REG6C, val)); RIE (sanei_genesys_write_register (dev, REG6C, val));
@ -1835,12 +1865,14 @@ dummy \ scanned lines
depth, depth,
half_ccd, half_ccd,
color_filter, color_filter,
((flags & SCAN_FLAG_DISABLE_SHADING) ((flags &
? OPTICAL_FLAG_DISABLE_SHADING : 0) SCAN_FLAG_DISABLE_SHADING) ?
| ((flags & SCAN_FLAG_DISABLE_GAMMA) OPTICAL_FLAG_DISABLE_SHADING : 0)
? OPTICAL_FLAG_DISABLE_GAMMA : 0) |
| ((flags & SCAN_FLAG_DISABLE_LAMP) ? ((flags & SCAN_FLAG_DISABLE_GAMMA)
OPTICAL_FLAG_DISABLE_LAMP : 0)); ? OPTICAL_FLAG_DISABLE_GAMMA : 0)
| ((flags & SCAN_FLAG_DISABLE_LAMP)
? OPTICAL_FLAG_DISABLE_LAMP : 0));
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
return status; return status;
@ -1902,7 +1934,8 @@ dummy \ scanned lines
scan_power_mode, scan_power_mode,
(flags & (flags &
SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE) SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE)
? MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE ?
MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE
: 0); : 0);
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
@ -2200,18 +2233,18 @@ dummy \ scanned lines
/* exposure_time */ /* exposure_time */
exposure_time = sanei_genesys_exposure_time2 (dev, exposure_time = sanei_genesys_exposure_time2 (dev,
slope_dpi, slope_dpi,
scan_step_type, scan_step_type,
0, 0,
led_exposure, led_exposure,
scan_power_mode); scan_power_mode);
while (scan_power_mode + 1 < dev->motor.power_mode_count) while (scan_power_mode + 1 < dev->motor.power_mode_count)
{ {
exposure_time2 = sanei_genesys_exposure_time2 (dev, exposure_time2 = sanei_genesys_exposure_time2 (dev,
slope_dpi, slope_dpi,
scan_step_type, scan_step_type,
0, 0,
led_exposure, led_exposure,
scan_power_mode + 1); scan_power_mode + 1);
if (exposure_time < exposure_time2) if (exposure_time < exposure_time2)
@ -2220,7 +2253,8 @@ dummy \ scanned lines
scan_power_mode++; scan_power_mode++;
} }
DBG (DBG_info, "gl847_calculate_current_setup : exposure_time=%d pixels\n", DBG (DBG_info,
"gl847_calculate_current_setup : exposure_time=%d pixels\n",
exposure_time); exposure_time);
/* max_shift */ /* max_shift */
@ -2291,8 +2325,8 @@ gl847_set_lamp_power (Genesys_Device * dev,
{ {
sanei_genesys_set_reg_from_set (regs, 0x03, sanei_genesys_set_reg_from_set (regs, 0x03,
sanei_genesys_read_reg_from_set (regs, sanei_genesys_read_reg_from_set (regs,
0x03) | 0x03)
REG03_LAMPPWR); | REG03_LAMPPWR);
r = sanei_genesys_get_address (regs, 0x10); r = sanei_genesys_get_address (regs, 0x10);
for (i = 0; i < 6; i++, r++) for (i = 0; i < 6; i++, r++)
@ -2309,8 +2343,8 @@ gl847_set_lamp_power (Genesys_Device * dev,
{ {
sanei_genesys_set_reg_from_set (regs, 0x03, sanei_genesys_set_reg_from_set (regs, 0x03,
sanei_genesys_read_reg_from_set (regs, sanei_genesys_read_reg_from_set (regs,
0x03) & 0x03)
~REG03_LAMPPWR); & ~REG03_LAMPPWR);
r = sanei_genesys_get_address (regs, 0x10); r = sanei_genesys_get_address (regs, 0x10);
for (i = 0; i < 6; i++, r++) for (i = 0; i < 6; i++, r++)
@ -2786,7 +2820,8 @@ gl847_detect_document_end (Genesys_Device * dev)
DBG (DBG_io, DBG (DBG_io,
"gl847_detect_document_end: total_bytes_to_read=%d\n", "gl847_detect_document_end: total_bytes_to_read=%d\n",
dev->total_bytes_to_read); dev->total_bytes_to_read);
DBG (DBG_io, "gl847_detect_document_end: read_bytes_left=%d\n", DBG (DBG_io,
"gl847_detect_document_end: read_bytes_left=%d\n",
read_bytes_left); read_bytes_left);
} }
} }
@ -2997,7 +3032,7 @@ gl847_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
{ {
print_status (val); print_status (val);
} }
usleep (100000); /* sleep 100 ms */ usleep (100000); /* sleep 100 ms */
/* second is reliable */ /* second is reliable */
status = sanei_genesys_get_status (dev, &val); status = sanei_genesys_get_status (dev, &val);
@ -3916,7 +3951,8 @@ gl847_init_gpio (Genesys_Device * dev)
RIE (sanei_genesys_read_register (dev, REG6C, &effective)); RIE (sanei_genesys_read_register (dev, REG6C, &effective));
if (effective != val) if (effective != val)
{ {
DBG (DBG_warn, "gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n", DBG (DBG_warn,
"gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n",
effective, val); effective, val);
} }
@ -3925,7 +3961,8 @@ gl847_init_gpio (Genesys_Device * dev)
RIE (sanei_genesys_read_register (dev, REG6C, &effective)); RIE (sanei_genesys_read_register (dev, REG6C, &effective));
if (effective != val) if (effective != val)
{ {
DBG (DBG_warn, "gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n", DBG (DBG_warn,
"gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n",
effective, val); effective, val);
} }
@ -3939,26 +3976,28 @@ gl847_init_gpio (Genesys_Device * dev)
RIE (sanei_genesys_read_register (dev, REG6C, &effective)); RIE (sanei_genesys_read_register (dev, REG6C, &effective));
if (effective != val) if (effective != val)
{ {
DBG (DBG_warn, "gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n", DBG (DBG_warn,
"gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n",
effective, val); effective, val);
} }
/* not done yet for LiDE 100 /* not done yet for LiDE 100
val = effective | 0x08; val = effective | 0x08;
RIE (sanei_genesys_write_register (dev, REG6C, val)); RIE (sanei_genesys_write_register (dev, REG6C, val));
RIE (sanei_genesys_read_register (dev, REG6C, &effective)); RIE (sanei_genesys_read_register (dev, REG6C, &effective));
if (effective != val) if (effective != val)
{ {
DBG (DBG_warn, "gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n", DBG (DBG_warn, "gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n",
effective, val); effective, val);
} */ } */
val = effective | 0x02; val = effective | 0x02;
RIE (sanei_genesys_write_register (dev, REG6C, val)); RIE (sanei_genesys_write_register (dev, REG6C, val));
RIE (sanei_genesys_read_register (dev, REG6C, &effective)); RIE (sanei_genesys_read_register (dev, REG6C, &effective));
if (effective != val) if (effective != val)
{ {
DBG (DBG_warn, "gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n", DBG (DBG_warn,
"gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n",
effective, val); effective, val);
} }
@ -3967,7 +4006,8 @@ gl847_init_gpio (Genesys_Device * dev)
RIE (sanei_genesys_read_register (dev, REG6C, &effective)); RIE (sanei_genesys_read_register (dev, REG6C, &effective));
if (effective != val) if (effective != val)
{ {
DBG (DBG_warn, "gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n", DBG (DBG_warn,
"gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n",
effective, val); effective, val);
} }
@ -4133,11 +4173,11 @@ gl847_init (Genesys_Device * dev)
/* Set default values for registers */ /* Set default values for registers */
gl847_init_registers (dev); gl847_init_registers (dev);
RIE (sanei_genesys_write_register(dev, REG6B,0x02)); RIE (sanei_genesys_write_register (dev, REG6B, 0x02));
RIE (sanei_genesys_write_register(dev, REG6C,0x00)); RIE (sanei_genesys_write_register (dev, REG6C, 0x00));
RIE (sanei_genesys_write_register(dev, REG6D,0x20)); RIE (sanei_genesys_write_register (dev, REG6D, 0x20));
RIE (sanei_genesys_write_register(dev, REG6E,0x7e)); RIE (sanei_genesys_write_register (dev, REG6E, 0x7e));
RIE (sanei_genesys_write_register(dev, REG6F,0x21)); RIE (sanei_genesys_write_register (dev, REG6F, 0x21));
/* Write initial registers */ /* Write initial registers */
RIE (gl847_bulk_write_register (dev, dev->reg, GENESYS_GL847_MAX_REGS)); RIE (gl847_bulk_write_register (dev, dev->reg, GENESYS_GL847_MAX_REGS));
@ -4433,8 +4473,8 @@ gl847_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
pass = 0; pass = 0;
if (DBG_LEVEL >= DBG_data) if (DBG_LEVEL >= DBG_data)
{ {
sprintf (title, "search_strip_%s_%s%02d.pnm", black ? "black" : "white", sprintf (title, "search_strip_%s_%s%02d.pnm",
forward ? "fwd" : "bwd", pass); black ? "black" : "white", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file (title, data, depth, channels, pixels, sanei_genesys_write_pnm_file (title, data, depth, channels, pixels,
lines); lines);
} }
@ -4492,8 +4532,8 @@ gl847_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
{ {
sprintf (title, "search_strip_%s_%s%02d.pnm", sprintf (title, "search_strip_%s_%s%02d.pnm",
black ? "black" : "white", forward ? "fwd" : "bwd", pass); black ? "black" : "white", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file (title, data, depth, channels, pixels, sanei_genesys_write_pnm_file (title, data, depth, channels,
lines); pixels, lines);
} }
/* search data to find black strip */ /* search data to find black strip */
@ -4572,8 +4612,8 @@ gl847_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
else else
{ {
DBG (DBG_data, DBG (DBG_data,
"gl847_search_strip: pixels=%d, count=%d (%d%%)\n", pixels, "gl847_search_strip: pixels=%d, count=%d (%d%%)\n",
count, (100 * count) / pixels); pixels, count, (100 * count) / pixels);
} }
} }
pass++; pass++;