summaryrefslogtreecommitdiff
path: root/backend/genesys/gl124.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backend/genesys/gl124.cpp')
-rw-r--r--backend/genesys/gl124.cpp1214
1 files changed, 168 insertions, 1046 deletions
diff --git a/backend/genesys/gl124.cpp b/backend/genesys/gl124.cpp
index 054f1ef..d3fc1bc 100644
--- a/backend/genesys/gl124.cpp
+++ b/backend/genesys/gl124.cpp
@@ -53,6 +53,37 @@
namespace genesys {
namespace gl124 {
+struct Gpio_layout
+{
+ std::uint8_t r31;
+ std::uint8_t r32;
+ std::uint8_t r33;
+ std::uint8_t r34;
+ std::uint8_t r35;
+ std::uint8_t r36;
+ std::uint8_t r38;
+};
+
+/** @brief gpio layout
+ * describes initial gpio settings for a given model
+ * registers 0x31 to 0x38
+ */
+static Gpio_layout gpios[] = {
+ /* LiDE 110 */
+ { /* 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38 */
+ 0x9f, 0x59, 0x01, 0x80, 0x5f, 0x01, 0x00
+ },
+ /* LiDE 210 */
+ {
+ 0x9f, 0x59, 0x01, 0x80, 0x5f, 0x01, 0x00
+ },
+ /* LiDE 120 */
+ {
+ 0x9f, 0x53, 0x01, 0x80, 0x5f, 0x01, 0x00
+ },
+};
+
+
/** @brief set all registers to default values .
* This function is called only once at the beginning and
* fills register startup values for registers reused across scans.
@@ -336,54 +367,9 @@ gl124_init_registers (Genesys_Device * dev)
// fine tune upon device description
const auto& sensor = sanei_genesys_find_sensor_any(dev);
- sanei_genesys_set_dpihw(dev->reg, sensor, sensor.optical_res);
-
- dev->calib_reg = dev->reg;
-}
-
-/**@brief send slope table for motor movement
- * Send slope_table in machine byte order
- * @param dev device to send slope table
- * @param table_nr index of the slope table in ASIC memory
- * Must be in the [0-4] range.
- * @param slope_table pointer to 16 bit values array of the slope table
- * @param steps number of elemnts in the slope table
- */
-static void gl124_send_slope_table(Genesys_Device* dev, int table_nr,
- const std::vector<uint16_t>& slope_table,
- int steps)
-{
- DBG_HELPER_ARGS(dbg, "table_nr = %d, steps = %d", table_nr, steps);
- int i;
- char msg[10000];
-
- /* sanity check */
- if(table_nr<0 || table_nr>4)
- {
- throw SaneException("invalid table number");
- }
-
- std::vector<uint8_t> table(steps * 2);
- for (i = 0; i < steps; i++)
- {
- table[i * 2] = slope_table[i] & 0xff;
- table[i * 2 + 1] = slope_table[i] >> 8;
- }
-
- if (DBG_LEVEL >= DBG_io)
- {
- std::sprintf(msg, "write slope %d (%d)=", table_nr, steps);
- for (i = 0; i < steps; i++) {
- std::sprintf(msg + std::strlen(msg), ",%d", slope_table[i]);
- }
- DBG (DBG_io, "%s: %s\n", __func__, msg);
- }
-
- if (dev->interface->is_mock()) {
- dev->interface->record_slope_table(table_nr, slope_table);
- }
- // slope table addresses are fixed
- dev->interface->write_ahb(0x10000000 + 0x4000 * table_nr, steps * 2, table.data());
+ const auto& dpihw_sensor = sanei_genesys_find_sensor(dev, sensor.full_resolution,
+ 3, ScanMethod::FLATBED);
+ sanei_genesys_set_dpihw(dev->reg, dpihw_sensor.register_dpihw);
}
/** @brief * Set register values of 'special' ti type frontend
@@ -397,12 +383,8 @@ static void gl124_set_ti_fe(Genesys_Device* dev, uint8_t set)
DBG_HELPER(dbg);
int i;
- if (set == AFE_INIT)
- {
- DBG(DBG_proc, "%s: setting DAC %u\n", __func__,
- static_cast<unsigned>(dev->model->adc_id));
-
- dev->frontend = dev->frontend_initial;
+ if (set == AFE_INIT) {
+ dev->frontend = dev->frontend_initial;
}
// start writing to DAC
@@ -441,11 +423,8 @@ void CommandSetGl124::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor,
(void) sensor;
uint8_t val;
- if (set == AFE_INIT)
- {
- DBG(DBG_proc, "%s(): setting DAC %u\n", __func__,
- static_cast<unsigned>(dev->model->adc_id));
- dev->frontend = dev->frontend_initial;
+ if (set == AFE_INIT) {
+ dev->frontend = dev->frontend_initial;
}
val = dev->interface->read_register(REG_0x0A);
@@ -466,14 +445,14 @@ void CommandSetGl124::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor,
static void gl124_init_motor_regs_scan(Genesys_Device* dev,
const Genesys_Sensor& sensor,
Genesys_Register_Set* reg,
- const Motor_Profile& motor_profile,
+ const MotorProfile& motor_profile,
unsigned int scan_exposure_time,
unsigned scan_yres,
unsigned int scan_lines,
unsigned int scan_dummy,
unsigned int feed_steps,
ScanColorMode scan_mode,
- MotorFlag flags)
+ ScanFlag flags)
{
DBG_HELPER(dbg);
int use_fast_fed;
@@ -533,11 +512,8 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev,
linesel=0;
}
- DBG(DBG_io2, "%s: final yres=%d, linesel=%d\n", __func__, yres, linesel);
-
lincnt=scan_lines*(linesel+1);
reg->set24(REG_LINCNT, lincnt);
- DBG (DBG_io, "%s: lincnt=%d\n", __func__, lincnt);
/* compute register 02 value */
uint8_t r02 = REG_0x02_NOTHOME;
@@ -548,15 +524,15 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev,
r02 &= ~REG_0x02_FASTFED;
}
- if (has_flag(flags, MotorFlag::AUTO_GO_HOME)) {
+ if (has_flag(flags, ScanFlag::AUTO_GO_HOME)) {
r02 |= REG_0x02_AGOHOME;
}
- if (has_flag(flags, MotorFlag::DISABLE_BUFFER_FULL_MOVE) || (yres >= sensor.optical_res))
+ if (has_flag(flags, ScanFlag::DISABLE_BUFFER_FULL_MOVE) || (yres >= sensor.full_resolution))
{
r02 |= REG_0x02_ACDCDIS;
}
- if (has_flag(flags, MotorFlag::REVERSE)) {
+ if (has_flag(flags, ScanFlag::REVERSE)) {
r02 |= REG_0x02_MTRREV;
}
@@ -566,13 +542,12 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev,
reg->set16(REG_SCANFED, 4);
/* scan and backtracking slope table */
- auto scan_table = sanei_genesys_slope_table(dev->model->asic_type, yres, scan_exposure_time,
- dev->motor.base_ydpi, 1,
- motor_profile);
- gl124_send_slope_table(dev, SCAN_TABLE, scan_table.table, scan_table.steps_count);
- gl124_send_slope_table(dev, BACKTRACK_TABLE, scan_table.table, scan_table.steps_count);
+ auto scan_table = create_slope_table(dev->model->asic_type, dev->motor, yres,
+ scan_exposure_time, 1, motor_profile);
+ scanner_send_slope_table(dev, sensor, SCAN_TABLE, scan_table.table);
+ scanner_send_slope_table(dev, sensor, BACKTRACK_TABLE, scan_table.table);
- reg->set16(REG_STEPNO, scan_table.steps_count);
+ reg->set16(REG_STEPNO, scan_table.table.size());
/* fast table */
fast_dpi=yres;
@@ -583,28 +558,26 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev,
fast_dpi*=3;
}
*/
- auto fast_table = sanei_genesys_slope_table(dev->model->asic_type, fast_dpi,
- scan_exposure_time, dev->motor.base_ydpi,
- 1, motor_profile);
- gl124_send_slope_table(dev, STOP_TABLE, fast_table.table, fast_table.steps_count);
- gl124_send_slope_table(dev, FAST_TABLE, fast_table.table, fast_table.steps_count);
+ auto fast_table = create_slope_table(dev->model->asic_type, dev->motor, fast_dpi,
+ scan_exposure_time, 1, motor_profile);
+ scanner_send_slope_table(dev, sensor, STOP_TABLE, fast_table.table);
+ scanner_send_slope_table(dev, sensor, FAST_TABLE, fast_table.table);
- reg->set16(REG_FASTNO, fast_table.steps_count);
- reg->set16(REG_FSHDEC, fast_table.steps_count);
- reg->set16(REG_FMOVNO, fast_table.steps_count);
+ reg->set16(REG_FASTNO, fast_table.table.size());
+ reg->set16(REG_FSHDEC, fast_table.table.size());
+ reg->set16(REG_FMOVNO, fast_table.table.size());
/* substract acceleration distance from feedl */
feedl=feed_steps;
feedl <<= static_cast<unsigned>(motor_profile.step_type);
- dist = scan_table.steps_count;
- if (has_flag(flags, MotorFlag::FEED)) {
+ dist = scan_table.table.size();
+ if (has_flag(flags, ScanFlag::FEEDING)) {
dist *= 2;
}
if (use_fast_fed) {
- dist += fast_table.steps_count * 2;
+ dist += fast_table.table.size() * 2;
}
- DBG (DBG_io2, "%s: acceleration distance=%d\n", __func__, dist);
/* get sure we don't use insane value */
if (dist < feedl) {
@@ -614,160 +587,97 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev,
}
reg->set24(REG_FEEDL, feedl);
- DBG (DBG_io, "%s: feedl=%d\n", __func__, feedl);
/* doesn't seem to matter that much */
sanei_genesys_calculate_zmod(use_fast_fed,
scan_exposure_time,
scan_table.table,
- scan_table.steps_count,
+ scan_table.table.size(),
feedl,
- scan_table.steps_count,
+ scan_table.table.size(),
&z1,
&z2);
reg->set24(REG_Z1MOD, z1);
- DBG(DBG_info, "%s: z1 = %d\n", __func__, z1);
-
reg->set24(REG_Z2MOD, z2);
- DBG(DBG_info, "%s: z2 = %d\n", __func__, z2);
/* LINESEL */
reg->set8_mask(REG_0x1D, linesel, REG_0x1D_LINESEL);
reg->set8(REG_0xA0, (static_cast<unsigned>(motor_profile.step_type) << REG_0xA0S_STEPSEL) |
(static_cast<unsigned>(motor_profile.step_type) << REG_0xA0S_FSTPSEL));
- reg->set16(REG_FMOVDEC, fast_table.steps_count);
+ reg->set16(REG_FMOVDEC, fast_table.table.size());
}
-
-/** @brief copy sensor specific settings
- * Set up register set for the given sensor resolution. Values are from the device table
- * in genesys_devices.c for registers:
- * [0x16 ... 0x1d]
- * [0x52 ... 0x5e]
- * Other come from the specific device sensor table in genesys_gl124.h:
- * 0x18, 0x20, 0x61, 0x98 and
- * @param dev device to set up
- * @param regs register set to modify
- * @param dpi resolution of the sensor during scan
- * @param ccd_size_divisor flag for half ccd mode
- * */
-static void gl124_setup_sensor(Genesys_Device* dev, const Genesys_Sensor& sensor,
- Genesys_Register_Set* regs)
-{
- DBG_HELPER(dbg);
-
- for (const auto& reg : sensor.custom_regs) {
- regs->set8(reg.address, reg.value);
- }
-
- regs->set24(REG_EXPR, sensor.exposure.red);
- regs->set24(REG_EXPG, sensor.exposure.green);
- regs->set24(REG_EXPB, sensor.exposure.blue);
-
- dev->segment_order = sensor.segment_order;
-}
-
-/** @brief setup optical related registers
- * start and pixels are expressed in optical sensor resolution coordinate
- * space.
- * @param dev scanner device to use
- * @param reg registers to set up
- * @param exposure_time exposure time to use
- * @param used_res scanning resolution used, may differ from
- * scan's one
- * @param start logical start pixel coordinate
- * @param pixels logical number of pixels to use
- * @param channels number of color channels (currently 1 or 3)
- * @param depth bit depth of the scan (1, 8 or 16)
- * @param ccd_size_divisor whether sensor's timings are such that x coordinates must be halved
- * @param color_filter color channel to use as gray data
- * @param flags optical flags (@see )
- */
static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sensor& sensor,
Genesys_Register_Set* reg, unsigned int exposure_time,
const ScanSession& session)
{
DBG_HELPER_ARGS(dbg, "exposure_time=%d", exposure_time);
- unsigned int dpihw;
- GenesysRegister *r;
uint32_t expmax;
- // resolution is divided according to ccd_pixels_per_system_pixel
- unsigned ccd_pixels_per_system_pixel = sensor.ccd_pixels_per_system_pixel();
- DBG(DBG_io2, "%s: ccd_pixels_per_system_pixel=%d\n", __func__, ccd_pixels_per_system_pixel);
-
- // to manage high resolution device while keeping good low resolution scanning speed, we
- // make hardware dpi vary
- dpihw = sensor.get_register_hwdpi(session.output_resolution * ccd_pixels_per_system_pixel);
- DBG(DBG_io2, "%s: dpihw=%d\n", __func__, dpihw);
-
- gl124_setup_sensor(dev, sensor, reg);
+ scanner_setup_sensor(*dev, sensor, *reg);
dev->cmd_set->set_fe(dev, sensor, AFE_SET);
/* enable shading */
regs_set_optical_off(dev->model->asic_type, *reg);
- r = sanei_genesys_get_address (reg, REG_0x01);
if (has_flag(session.params.flags, ScanFlag::DISABLE_SHADING) ||
- (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION))
+ has_flag(dev->model->flags, ModelFlag::DISABLE_SHADING_CALIBRATION))
{
- r->value &= ~REG_0x01_DVDSET;
+ reg->find_reg(REG_0x01).value &= ~REG_0x01_DVDSET;
} else {
- r->value |= REG_0x01_DVDSET;
+ reg->find_reg(REG_0x01).value |= REG_0x01_DVDSET;
}
- r = sanei_genesys_get_address(reg, REG_0x03);
if ((dev->model->sensor_id != SensorId::CIS_CANON_LIDE_120) && (session.params.xres>=600)) {
- r->value &= ~REG_0x03_AVEENB;
- DBG (DBG_io, "%s: disabling AVEENB\n", __func__);
- }
- else
- {
- r->value |= ~REG_0x03_AVEENB;
- DBG (DBG_io, "%s: enabling AVEENB\n", __func__);
+ reg->find_reg(REG_0x03).value &= ~REG_0x03_AVEENB;
+ } else {
+ // BUG: the following is likely incorrect
+ reg->find_reg(REG_0x03).value |= ~REG_0x03_AVEENB;
}
sanei_genesys_set_lamp_power(dev, sensor, *reg,
!has_flag(session.params.flags, ScanFlag::DISABLE_LAMP));
// BW threshold
- dev->interface->write_register(REG_0x114, dev->settings.threshold);
- dev->interface->write_register(REG_0x115, dev->settings.threshold);
+ dev->interface->write_register(REG_0x114, 0x7f);
+ dev->interface->write_register(REG_0x115, 0x7f);
/* monochrome / color scan */
- r = sanei_genesys_get_address (reg, REG_0x04);
switch (session.params.depth) {
case 8:
- r->value &= ~(REG_0x04_LINEART | REG_0x04_BITSET);
+ reg->find_reg(REG_0x04).value &= ~(REG_0x04_LINEART | REG_0x04_BITSET);
break;
case 16:
- r->value &= ~REG_0x04_LINEART;
- r->value |= REG_0x04_BITSET;
+ reg->find_reg(REG_0x04).value &= ~REG_0x04_LINEART;
+ reg->find_reg(REG_0x04).value |= REG_0x04_BITSET;
break;
}
- r->value &= ~REG_0x04_FILTER;
+ reg->find_reg(REG_0x04).value &= ~REG_0x04_FILTER;
if (session.params.channels == 1)
{
switch (session.params.color_filter)
{
case ColorFilter::RED:
- r->value |= 0x10;
+ reg->find_reg(REG_0x04).value |= 0x10;
break;
case ColorFilter::BLUE:
- r->value |= 0x30;
+ reg->find_reg(REG_0x04).value |= 0x30;
break;
case ColorFilter::GREEN:
- r->value |= 0x20;
+ reg->find_reg(REG_0x04).value |= 0x20;
break;
default:
break; // should not happen
}
}
- sanei_genesys_set_dpihw(*reg, sensor, dpihw);
+ const auto& dpihw_sensor = sanei_genesys_find_sensor(dev, session.output_resolution,
+ session.params.channels,
+ session.params.scan_method);
+ sanei_genesys_set_dpihw(*reg, dpihw_sensor.register_dpihw);
if (should_enable_gamma(session, sensor)) {
reg->find_reg(REG_0x05).value |= REG_0x05_GMMENB;
@@ -775,25 +685,16 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
reg->find_reg(REG_0x05).value &= ~REG_0x05_GMMENB;
}
- unsigned dpiset_reg = session.output_resolution * ccd_pixels_per_system_pixel *
- session.ccd_size_divisor;
- if (sensor.dpiset_override != 0) {
- dpiset_reg = sensor.dpiset_override;
- }
-
- reg->set16(REG_DPISET, dpiset_reg);
- DBG (DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset_reg);
+ reg->set16(REG_DPISET, sensor.register_dpiset);
- r = sanei_genesys_get_address(reg, REG_0x06);
- r->value |= REG_0x06_GAIN4;
+ reg->find_reg(REG_0x06).value |= REG_0x06_GAIN4;
/* CIS scanners can do true gray by setting LEDADD */
/* we set up LEDADD only when asked */
if (dev->model->is_cis) {
- r = sanei_genesys_get_address (reg, REG_0x60);
- r->value &= ~REG_0x60_LEDADD;
+ reg->find_reg(REG_0x60).value &= ~REG_0x60_LEDADD;
if (session.enable_ledadd) {
- r->value |= REG_0x60_LEDADD;
+ reg->find_reg(REG_0x60).value |= REG_0x60_LEDADD;
expmax = reg->get24(REG_EXPR);
expmax = std::max(expmax, reg->get24(REG_EXPG));
expmax = std::max(expmax, reg->get24(REG_EXPB));
@@ -803,31 +704,32 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
dev->reg.set24(REG_EXPB, expmax);
}
/* RGB weighting, REG_TRUER,G and B are to be set */
- r = sanei_genesys_get_address (reg, 0x01);
- r->value &= ~REG_0x01_TRUEGRAY;
+ reg->find_reg(0x01).value &= ~REG_0x01_TRUEGRAY;
if (session.enable_ledadd) {
- r->value |= REG_0x01_TRUEGRAY;
+ reg->find_reg(0x01).value |= REG_0x01_TRUEGRAY;
dev->interface->write_register(REG_TRUER, 0x80);
dev->interface->write_register(REG_TRUEG, 0x80);
dev->interface->write_register(REG_TRUEB, 0x80);
}
}
+ std::uint32_t pixel_endx = session.pixel_endx;
+ if (pixel_endx == reg->get24(REG_SEGCNT)) {
+ pixel_endx = 0;
+ }
reg->set24(REG_STRPIXEL, session.pixel_startx);
- reg->set24(REG_ENDPIXEL, session.pixel_endx);
+ reg->set24(REG_ENDPIXEL, pixel_endx);
dev->line_count = 0;
- build_image_pipeline(dev, session);
+ setup_image_pipeline(*dev, session);
// MAXWD is expressed in 2 words unit
// BUG: we shouldn't multiply by channels here
- reg->set24(REG_MAXWD, session.output_line_bytes_raw / session.ccd_size_divisor * session.params.channels);
-
+ reg->set24(REG_MAXWD, session.output_line_bytes_raw * session.params.channels *
+ session.optical_resolution / session.full_resolution);
reg->set24(REG_LPERIOD, exposure_time);
- DBG (DBG_io2, "%s: exposure_time used=%d\n", __func__, exposure_time);
-
reg->set16(REG_DUMMY, sensor.dummy_pixel);
}
@@ -838,7 +740,6 @@ void CommandSetGl124::init_regs_for_scan_session(Genesys_Device* dev, const Gene
DBG_HELPER(dbg);
session.assert_computed();
- int move;
int exposure_time;
int dummy = 0;
@@ -856,9 +757,7 @@ void CommandSetGl124::init_regs_for_scan_session(Genesys_Device* dev, const Gene
} else {
exposure_time = sensor.exposure_lperiod;
}
- const auto& motor_profile = sanei_genesys_get_motor_profile(*gl124_motor_profiles,
- dev->model->motor_id,
- exposure_time);
+ const auto& motor_profile = get_motor_profile(dev->motor.profiles, exposure_time, session);
DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time);
DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, static_cast<unsigned>(motor_profile.step_type));
@@ -870,30 +769,13 @@ void CommandSetGl124::init_regs_for_scan_session(Genesys_Device* dev, const Gene
// now _LOGICAL_ optical values used are known, setup registers
gl124_init_optical_regs_scan(dev, sensor, reg, exposure_time, session);
- /* add tl_y to base movement */
- move = session.params.starty;
- DBG(DBG_info, "%s: move=%d steps\n", __func__, move);
-
- MotorFlag mflags = MotorFlag::NONE;
- if (has_flag(session.params.flags, ScanFlag::DISABLE_BUFFER_FULL_MOVE)) {
- mflags |= MotorFlag::DISABLE_BUFFER_FULL_MOVE;
- }
- if (has_flag(session.params.flags, ScanFlag::FEEDING)) {
- mflags |= MotorFlag::FEED;
- }
- if (has_flag(session.params.flags, ScanFlag::REVERSE)) {
- mflags |= MotorFlag::REVERSE;
- }
gl124_init_motor_regs_scan(dev, sensor, reg, motor_profile, exposure_time, slope_dpi,
- dev->model->is_cis ? session.output_line_count * session.params.channels :
- session.output_line_count,
- dummy, move, session.params.scan_mode, mflags);
+ session.optical_line_count,
+ dummy, session.params.starty, session.params.scan_mode,
+ session.params.flags);
/*** prepares data reordering ***/
- dev->read_buffer.clear();
- dev->read_buffer.alloc(session.buffer_size_read);
-
dev->read_active = true;
dev->session = session;
@@ -909,21 +791,24 @@ ScanSession CommandSetGl124::calculate_scan_session(const Genesys_Device* dev,
const Genesys_Sensor& sensor,
const Genesys_Settings& settings) const
{
- int start;
-
DBG(DBG_info, "%s ", __func__);
debug_dump(DBG_info, settings);
- /* start */
- start = static_cast<int>(dev->model->x_offset);
- start += static_cast<int>(settings.tl_x);
- start = static_cast<int>((start * sensor.optical_res) / MM_PER_INCH);
+ unsigned move_dpi = dev->motor.base_ydpi / 4;
+ float move = dev->model->y_offset;
+ move += dev->settings.tl_y;
+ move = static_cast<float>((move * move_dpi) / MM_PER_INCH);
+
+ float start = dev->model->x_offset;
+ start += settings.tl_x;
+ start /= sensor.full_resolution / sensor.get_optical_resolution();
+ start = static_cast<float>((start * settings.xres) / MM_PER_INCH);
ScanSession session;
session.params.xres = settings.xres;
session.params.yres = settings.yres;
- session.params.startx = start;
- session.params.starty = 0; // not used
+ session.params.startx = static_cast<unsigned>(start);
+ session.params.starty = static_cast<unsigned>(move);
session.params.pixels = settings.pixels;
session.params.requested_pixels = settings.requested_pixels;
session.params.lines = settings.lines;
@@ -953,17 +838,15 @@ void CommandSetGl124::save_power(Genesys_Device* dev, bool enable) const
void CommandSetGl124::set_powersaving(Genesys_Device* dev, int delay /* in minutes */) const
{
DBG_HELPER_ARGS(dbg, "delay = %d", delay);
- GenesysRegister *r;
- r = sanei_genesys_get_address(&dev->reg, REG_0x03);
- r->value &= ~0xf0;
+ dev->reg.find_reg(REG_0x03).value &= ~0xf0;
if(delay<15)
{
- r->value |= delay;
+ dev->reg.find_reg(REG_0x03).value |= delay;
}
else
{
- r->value |= 0x0f;
+ dev->reg.find_reg(REG_0x03).value |= 0x0f;
}
}
@@ -1031,8 +914,7 @@ void CommandSetGl124::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens
// set up GPIO for scan
gl124_setup_scan_gpio(dev,dev->settings.yres);
- // clear scan and feed count
- dev->interface->write_register(REG_0x0D, REG_0x0D_CLRLNCNT | REG_0x0D_CLRMCNT);
+ scanner_clear_scan_and_feed_counts(*dev);
// enable scan and motor
uint8_t val = dev->interface->read_register(REG_0x01);
@@ -1069,177 +951,43 @@ void CommandSetGl124::move_back_home(Genesys_Device* dev, bool wait_until_home)
scanner_move_back_home(*dev, wait_until_home);
}
-// Automatically set top-left edge of the scan area by scanning a 200x200 pixels area at 600 dpi
-// from very top of scanner
-void CommandSetGl124::search_start_position(Genesys_Device* dev) const
-{
- DBG_HELPER(dbg);
- int size;
- Genesys_Register_Set local_reg = dev->reg;
-
- int pixels = 600;
- int dpi = 300;
-
- /* sets for a 200 lines * 600 pixels */
- /* normal scan with no shading */
-
- // FIXME: the current approach of doing search only for one resolution does not work on scanners
- // whith employ different sensors with potentially different settings.
- const auto& sensor = sanei_genesys_find_sensor(dev, dpi, 1, ScanMethod::FLATBED);
-
- ScanSession session;
- session.params.xres = dpi;
- session.params.yres = dpi;
- session.params.startx = 0;
- session.params.starty = 0; /*we should give a small offset here~60 steps */
- session.params.pixels = 600;
- session.params.lines = dev->model->search_lines;
- session.params.depth = 8;
- session.params.channels = 1;
- session.params.scan_method = dev->settings.scan_method;
- session.params.scan_mode = ScanColorMode::GRAY;
- session.params.color_filter = ColorFilter::GREEN;
- session.params.flags = ScanFlag::DISABLE_SHADING |
- ScanFlag::DISABLE_GAMMA |
- ScanFlag::IGNORE_LINE_DISTANCE |
- ScanFlag::DISABLE_BUFFER_FULL_MOVE;
- compute_session(dev, session, sensor);
-
- init_regs_for_scan_session(dev, sensor, &local_reg, session);
-
- // send to scanner
- dev->interface->write_registers(local_reg);
-
- size = pixels * dev->model->search_lines;
-
- std::vector<uint8_t> data(size);
-
- begin_scan(dev, sensor, &local_reg, true);
-
- if (is_testing_mode()) {
- dev->interface->test_checkpoint("search_start_position");
- end_scan(dev, &local_reg, true);
- dev->reg = local_reg;
- return;
- }
-
- wait_until_buffer_non_empty(dev);
-
- // now we're on target, we can read data
- sanei_genesys_read_data_from_scanner(dev, data.data(), size);
-
- if (DBG_LEVEL >= DBG_data) {
- sanei_genesys_write_pnm_file("gl124_search_position.pnm", data.data(), 8, 1, pixels,
- dev->model->search_lines);
- }
-
- end_scan(dev, &local_reg, true);
-
- /* update regs to copy ASIC internal state */
- dev->reg = local_reg;
-
- for (auto& sensor_update :
- sanei_genesys_find_sensors_all_for_write(dev, dev->model->default_method))
- {
- sanei_genesys_search_reference_point(dev, sensor_update, data.data(), 0, dpi, pixels,
- dev->model->search_lines);
- }
-}
-
-// sets up register for coarse gain calibration
-// todo: check it for scanners using it
-void CommandSetGl124::init_regs_for_coarse_calibration(Genesys_Device* dev,
- const Genesys_Sensor& sensor,
- Genesys_Register_Set& regs) const
-{
- DBG_HELPER(dbg);
-
- ScanSession session;
- session.params.xres = dev->settings.xres;
- session.params.yres = dev->settings.yres;
- session.params.startx = 0;
- session.params.starty = 0;
- session.params.pixels = sensor.optical_res / sensor.ccd_pixels_per_system_pixel();
- session.params.lines = 20;
- session.params.depth = 16;
- session.params.channels = dev->settings.get_channels();
- session.params.scan_method = dev->settings.scan_method;
- session.params.scan_mode = dev->settings.scan_mode;
- session.params.color_filter = dev->settings.color_filter;
- session.params.flags = ScanFlag::DISABLE_SHADING |
- ScanFlag::DISABLE_GAMMA |
- ScanFlag::SINGLE_LINE |
- ScanFlag::FEEDING |
- ScanFlag::IGNORE_LINE_DISTANCE;
- compute_session(dev, session, sensor);
-
- init_regs_for_scan_session(dev, sensor, &regs, session);
-
- sanei_genesys_set_motor_power(regs, false);
-
- DBG(DBG_info, "%s: optical sensor res: %d dpi, actual res: %d\n", __func__,
- sensor.optical_res / sensor.ccd_pixels_per_system_pixel(), dev->settings.xres);
-
- dev->interface->write_registers(regs);
-}
-
-
// init registers for shading calibration shading calibration is done at dpihw
void CommandSetGl124::init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor,
Genesys_Register_Set& regs) const
{
DBG_HELPER(dbg);
- int move, resolution, dpihw, factor;
-
- /* initial calibration reg values */
- regs = dev->reg;
-
- dev->calib_channels = 3;
- dev->calib_lines = dev->model->shading_lines;
- dpihw = sensor.get_register_hwdpi(dev->settings.xres);
- if(dpihw>=2400)
- {
- dev->calib_lines *= 2;
- }
- resolution=dpihw;
- unsigned ccd_size_divisor = sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres);
+ unsigned channels = 3;
+ unsigned resolution = sensor.shading_resolution;
- resolution /= ccd_size_divisor;
- dev->calib_lines /= ccd_size_divisor; // reducing just because we reduced the resolution
+ unsigned calib_lines =
+ static_cast<unsigned>(dev->model->y_size_calib_mm * resolution / MM_PER_INCH);
- const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution,
- dev->calib_channels,
+ const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, channels,
dev->settings.scan_method);
- dev->calib_resolution = resolution;
- dev->calib_total_bytes_to_read = 0;
- factor = calib_sensor.optical_res / resolution;
- dev->calib_pixels = calib_sensor.sensor_pixels / factor;
/* distance to move to reach white target at high resolution */
- move=0;
+ unsigned move=0;
if (dev->settings.yres >= 1200) {
move = static_cast<int>(dev->model->y_offset_calib_white);
move = static_cast<int>((move * (dev->motor.base_ydpi/4)) / MM_PER_INCH);
}
- DBG (DBG_io, "%s: move=%d steps\n", __func__, move);
ScanSession session;
session.params.xres = resolution;
session.params.yres = resolution;
session.params.startx = 0;
session.params.starty = move;
- session.params.pixels = dev->calib_pixels;
- session.params.lines = dev->calib_lines;
+ session.params.pixels = dev->model->x_size_calib_mm * resolution / MM_PER_INCH;
+ session.params.lines = calib_lines;
session.params.depth = 16;
- session.params.channels = dev->calib_channels;
+ session.params.channels = channels;
session.params.scan_method = dev->settings.scan_method;
session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS;
session.params.color_filter = ColorFilter::RED;
session.params.flags = ScanFlag::DISABLE_SHADING |
ScanFlag::DISABLE_GAMMA |
- ScanFlag::DISABLE_BUFFER_FULL_MOVE |
- ScanFlag::IGNORE_LINE_DISTANCE;
+ ScanFlag::DISABLE_BUFFER_FULL_MOVE;
compute_session(dev, session, calib_sensor);
try {
@@ -1250,7 +998,7 @@ void CommandSetGl124::init_regs_for_shading(Genesys_Device* dev, const Genesys_S
}
sanei_genesys_set_motor_power(regs, false);
- dev->interface->write_registers(regs);
+ dev->calib_session = session;
}
void CommandSetGl124::wait_for_motor_stop(Genesys_Device* dev) const
@@ -1272,56 +1020,6 @@ void CommandSetGl124::wait_for_motor_stop(Genesys_Device* dev) const
dev->interface->sleep_ms(50);
}
-/** @brief set up registers for the actual scan
- */
-void CommandSetGl124::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const
-{
- DBG_HELPER(dbg);
- float move;
- int move_dpi;
- float start;
-
- debug_dump(DBG_info, dev->settings);
-
- /* y (motor) distance to move to reach scanned area */
- move_dpi = dev->motor.base_ydpi/4;
- move = static_cast<float>(dev->model->y_offset);
- move += static_cast<float>(dev->settings.tl_y);
- move = static_cast<float>((move * move_dpi) / MM_PER_INCH);
- DBG (DBG_info, "%s: move=%f steps\n", __func__, move);
-
- if (dev->settings.get_channels() * dev->settings.yres >= 600 && move > 700) {
- scanner_move(*dev, dev->model->default_method, static_cast<unsigned>(move - 500),
- Direction::FORWARD);
- move=500;
- }
- DBG(DBG_info, "%s: move=%f steps\n", __func__, move);
-
- /* start */
- start = static_cast<float>(dev->model->x_offset);
- start += static_cast<float>(dev->settings.tl_x);
- start /= sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres);
- start = static_cast<float>((start * sensor.optical_res) / MM_PER_INCH);
-
- ScanSession session;
- session.params.xres = dev->settings.xres;
- session.params.yres = dev->settings.yres;
- session.params.startx = static_cast<unsigned>(start);
- session.params.starty = static_cast<unsigned>(move);
- session.params.pixels = dev->settings.pixels;
- session.params.requested_pixels = dev->settings.requested_pixels;
- session.params.lines = dev->settings.lines;
- session.params.depth = dev->settings.depth;
- session.params.channels = dev->settings.get_channels();
- session.params.scan_method = dev->settings.scan_method;
- session.params.scan_mode = dev->settings.scan_mode;
- session.params.color_filter = dev->settings.color_filter;
- session.params.flags = ScanFlag::NONE;
- compute_session(dev, session, sensor);
-
- init_regs_for_scan_session(dev, sensor, &dev->reg, session);
-}
-
/**
* Send shading calibration data. The buffer is considered to always hold values
* for all the channels.
@@ -1330,8 +1028,7 @@ void CommandSetGl124::send_shading_data(Genesys_Device* dev, const Genesys_Senso
std::uint8_t* data, int size) const
{
DBG_HELPER_ARGS(dbg, "writing %d bytes of shading data", size);
- uint32_t addr, length, x, factor, segcnt, pixels, i;
- uint16_t dpiset,dpihw;
+ std::uint32_t addr, length, segcnt, pixels, i;
uint8_t *ptr, *src;
/* logical size of a color as seen by generic code of the frontend */
@@ -1339,16 +1036,6 @@ void CommandSetGl124::send_shading_data(Genesys_Device* dev, const Genesys_Senso
std::uint32_t strpixel = dev->session.pixel_startx;
std::uint32_t endpixel = dev->session.pixel_endx;
segcnt = dev->reg.get24(REG_SEGCNT);
- if(endpixel==0)
- {
- endpixel=segcnt;
- }
-
- /* compute deletion factor */
- dpiset = dev->reg.get16(REG_DPISET);
- dpihw = sensor.get_register_hwdpi(dpiset);
- factor=dpihw/dpiset;
- DBG( DBG_io2, "%s: factor=%d\n",__func__,factor);
/* turn pixel value into bytes 2x16 bits words */
strpixel*=2*2; /* 2 words of 2 bytes */
@@ -1359,7 +1046,7 @@ void CommandSetGl124::send_shading_data(Genesys_Device* dev, const Genesys_Senso
dev->interface->record_key_value("shading_start_pixel", std::to_string(strpixel));
dev->interface->record_key_value("shading_pixels", std::to_string(pixels));
dev->interface->record_key_value("shading_length", std::to_string(length));
- dev->interface->record_key_value("shading_factor", std::to_string(factor));
+ dev->interface->record_key_value("shading_factor", std::to_string(sensor.shading_factor));
dev->interface->record_key_value("shading_segcnt", std::to_string(segcnt));
dev->interface->record_key_value("shading_segment_count",
std::to_string(dev->session.segment_count));
@@ -1375,47 +1062,18 @@ void CommandSetGl124::send_shading_data(Genesys_Device* dev, const Genesys_Senso
ptr = buffer.data();
/* iterate on both sensor segment */
- for(x=0;x<pixels;x+=4*factor)
- {
+ for (unsigned x = 0; x < pixels; x += 4 * sensor.shading_factor) {
/* coefficient source */
src=data+x+strpixel+i*length;
/* iterate over all the segments */
- switch (dev->session.segment_count) {
- case 1:
- ptr[0+pixels*0]=src[0+segcnt*0];
- ptr[1+pixels*0]=src[1+segcnt*0];
- ptr[2+pixels*0]=src[2+segcnt*0];
- ptr[3+pixels*0]=src[3+segcnt*0];
- break;
- case 2:
- ptr[0+pixels*0]=src[0+segcnt*0];
- ptr[1+pixels*0]=src[1+segcnt*0];
- ptr[2+pixels*0]=src[2+segcnt*0];
- ptr[3+pixels*0]=src[3+segcnt*0];
- ptr[0+pixels*1]=src[0+segcnt*1];
- ptr[1+pixels*1]=src[1+segcnt*1];
- ptr[2+pixels*1]=src[2+segcnt*1];
- ptr[3+pixels*1]=src[3+segcnt*1];
- break;
- case 4:
- ptr[0+pixels*0]=src[0+segcnt*0];
- ptr[1+pixels*0]=src[1+segcnt*0];
- ptr[2+pixels*0]=src[2+segcnt*0];
- ptr[3+pixels*0]=src[3+segcnt*0];
- ptr[0+pixels*1]=src[0+segcnt*2];
- ptr[1+pixels*1]=src[1+segcnt*2];
- ptr[2+pixels*1]=src[2+segcnt*2];
- ptr[3+pixels*1]=src[3+segcnt*2];
- ptr[0+pixels*2]=src[0+segcnt*1];
- ptr[1+pixels*2]=src[1+segcnt*1];
- ptr[2+pixels*2]=src[2+segcnt*1];
- ptr[3+pixels*2]=src[3+segcnt*1];
- ptr[0+pixels*3]=src[0+segcnt*3];
- ptr[1+pixels*3]=src[1+segcnt*3];
- ptr[2+pixels*3]=src[2+segcnt*3];
- ptr[3+pixels*3]=src[3+segcnt*3];
- break;
+ for (unsigned s = 0; s < dev->session.segment_count; s++)
+ {
+ unsigned segnum = dev->session.segment_count > 1 ? sensor.segment_order[s] : 0;
+ ptr[0+pixels*s]=src[0+segcnt*segnum];
+ ptr[1+pixels*s]=src[1+segcnt*segnum];
+ ptr[2+pixels*s]=src[2+segcnt*segnum];
+ ptr[3+pixels*s]=src[3+segcnt*segnum];
}
/* next shading coefficient */
@@ -1433,20 +1091,17 @@ void CommandSetGl124::send_shading_data(Genesys_Device* dev, const Genesys_Senso
* by doing a 600 dpi scan
* @param dev scanner device
*/
-static void move_to_calibration_area(Genesys_Device* dev, const Genesys_Sensor& sensor,
- Genesys_Register_Set& regs)
+void move_to_calibration_area(Genesys_Device* dev, const Genesys_Sensor& sensor,
+ Genesys_Register_Set& regs)
{
(void) sensor;
DBG_HELPER(dbg);
- int pixels;
- int size;
unsigned resolution = 600;
unsigned channels = 3;
const auto& move_sensor = sanei_genesys_find_sensor(dev, resolution, channels,
dev->settings.scan_method);
- pixels = (move_sensor.sensor_pixels * 600) / move_sensor.optical_res;
/* initial calibration reg values */
regs = dev->reg;
@@ -1456,7 +1111,7 @@ static void move_to_calibration_area(Genesys_Device* dev, const Genesys_Sensor&
session.params.yres = resolution;
session.params.startx = 0;
session.params.starty = 0;
- session.params.pixels = pixels;
+ session.params.pixels = dev->model->x_size_calib_mm * resolution / MM_PER_INCH;
session.params.lines = 1;
session.params.depth = 8;
session.params.channels = channels;
@@ -1466,14 +1121,12 @@ static void move_to_calibration_area(Genesys_Device* dev, const Genesys_Sensor&
session.params.flags = ScanFlag::DISABLE_SHADING |
ScanFlag::DISABLE_GAMMA |
ScanFlag::SINGLE_LINE |
- ScanFlag::IGNORE_LINE_DISTANCE;
+ ScanFlag::IGNORE_STAGGER_OFFSET |
+ ScanFlag::IGNORE_COLOR_OFFSET;
compute_session(dev, session, move_sensor);
dev->cmd_set->init_regs_for_scan_session(dev, move_sensor, &regs, session);
- size = pixels * 3;
- std::vector<uint8_t> line(size);
-
// write registers and scan data
dev->interface->write_registers(regs);
@@ -1486,14 +1139,13 @@ static void move_to_calibration_area(Genesys_Device* dev, const Genesys_Sensor&
return;
}
- sanei_genesys_read_data_from_scanner(dev, line.data(), size);
+ auto image = read_unshuffled_image_from_scanner(dev, session, session.output_line_bytes);
// stop scanning
scanner_stop_action(*dev);
- if (DBG_LEVEL >= DBG_data)
- {
- sanei_genesys_write_pnm_file("gl124_movetocalarea.pnm", line.data(), 8, 3, pixels, 1);
+ if (dbg_log_image_data()) {
+ write_tiff_file("gl124_movetocalarea.tiff", image);
}
}
@@ -1505,513 +1157,60 @@ static void move_to_calibration_area(Genesys_Device* dev, const Genesys_Sensor&
SensorExposure CommandSetGl124::led_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor,
Genesys_Register_Set& regs) const
{
- DBG_HELPER(dbg);
- int num_pixels;
- int total_size;
- int resolution;
- int dpihw;
- int i, j;
- int val;
- int channels;
- int avg[3];
- int turn;
- uint16_t exp[3],target;
-
- /* move to calibration area */
- move_to_calibration_area(dev, sensor, regs);
-
- /* offset calibration is always done in 16 bit depth color mode */
- channels = 3;
- dpihw = sensor.get_register_hwdpi(dev->settings.xres);
- resolution = dpihw;
- unsigned ccd_size_divisor = sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres);
- resolution /= ccd_size_divisor;
-
- const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, channels,
- dev->settings.scan_method);
- num_pixels = (calib_sensor.sensor_pixels * resolution) / calib_sensor.optical_res;
-
- /* initial calibration reg values */
- regs = dev->reg;
-
- ScanSession session;
- session.params.xres = resolution;
- session.params.yres = resolution;
- session.params.startx = 0;
- session.params.starty = 0;
- session.params.pixels = num_pixels;
- session.params.lines = 1;
- session.params.depth = 16;
- session.params.channels = channels;
- session.params.scan_method = dev->settings.scan_method;
- session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS;
- session.params.color_filter = dev->settings.color_filter;
- session.params.flags = ScanFlag::DISABLE_SHADING |
- ScanFlag::DISABLE_GAMMA |
- ScanFlag::SINGLE_LINE |
- ScanFlag::IGNORE_LINE_DISTANCE;
- compute_session(dev, session, calib_sensor);
-
- init_regs_for_scan_session(dev, calib_sensor, &regs, session);
-
- total_size = num_pixels * channels * (session.params.depth / 8) * 1;
- std::vector<uint8_t> line(total_size);
-
- // initial loop values and boundaries
- exp[0] = calib_sensor.exposure.red;
- exp[1] = calib_sensor.exposure.green;
- exp[2] = calib_sensor.exposure.blue;
- target=sensor.gain_white_ref*256;
-
- turn = 0;
-
- /* no move during led calibration */
- sanei_genesys_set_motor_power(regs, false);
- bool acceptable = false;
- do
- {
- // set up exposure
- regs.set24(REG_EXPR, exp[0]);
- regs.set24(REG_EXPG, exp[1]);
- regs.set24(REG_EXPB, exp[2]);
-
- // write registers and scan data
- dev->interface->write_registers(regs);
-
- DBG(DBG_info, "%s: starting line reading\n", __func__);
- begin_scan(dev, calib_sensor, &regs, true);
-
- if (is_testing_mode()) {
- dev->interface->test_checkpoint("led_calibration");
- scanner_stop_action(*dev);
- return calib_sensor.exposure;
- }
-
- sanei_genesys_read_data_from_scanner(dev, line.data(), total_size);
-
- // stop scanning
- scanner_stop_action(*dev);
-
- if (DBG_LEVEL >= DBG_data)
- {
- char fn[30];
- std::snprintf(fn, 30, "gl124_led_%02d.pnm", turn);
- sanei_genesys_write_pnm_file(fn, line.data(), session.params.depth, channels, num_pixels,
- 1);
- }
-
- /* compute average */
- for (j = 0; j < channels; j++)
- {
- avg[j] = 0;
- for (i = 0; i < num_pixels; i++)
- {
- if (dev->model->is_cis)
- val =
- line[i * 2 + j * 2 * num_pixels + 1] * 256 +
- line[i * 2 + j * 2 * num_pixels];
- else
- val =
- line[i * 2 * channels + 2 * j + 1] * 256 +
- line[i * 2 * channels + 2 * j];
- avg[j] += val;
- }
-
- avg[j] /= num_pixels;
- }
-
- DBG(DBG_info, "%s: average: %d,%d,%d\n", __func__, avg[0], avg[1], avg[2]);
-
- /* check if exposure gives average within the boundaries */
- acceptable = true;
- for(i=0;i<3;i++)
- {
- /* we accept +- 2% delta from target */
- if(abs(avg[i]-target)>target/50)
- {
- float prev_weight = 0.5;
- exp[i] = exp[i] * prev_weight + ((exp[i] * target) / avg[i]) * (1 - prev_weight);
- acceptable = false;
- }
- }
-
- turn++;
- }
- while (!acceptable && turn < 100);
-
- DBG(DBG_info, "%s: acceptable exposure: %d,%d,%d\n", __func__, exp[0], exp[1], exp[2]);
-
- // set these values as final ones for scan
- dev->reg.set24(REG_EXPR, exp[0]);
- dev->reg.set24(REG_EXPG, exp[1]);
- dev->reg.set24(REG_EXPB, exp[2]);
-
- return { exp[0], exp[1], exp[2] };
+ return scanner_led_calibration(*dev, sensor, regs);
}
-/**
- * average dark pixels of a 8 bits scan
- */
-static int
-dark_average (uint8_t * data, unsigned int pixels, unsigned int lines,
- unsigned int channels, unsigned int black)
-{
- unsigned int i, j, k, average, count;
- unsigned int avg[3];
- uint8_t val;
-
- /* computes average value on black margin */
- for (k = 0; k < channels; k++)
- {
- avg[k] = 0;
- count = 0;
- for (i = 0; i < lines; i++)
- {
- for (j = 0; j < black; j++)
- {
- val = data[i * channels * pixels + j + k];
- avg[k] += val;
- count++;
- }
- }
- if (count)
- avg[k] /= count;
- DBG(DBG_info, "%s: avg[%d] = %d\n", __func__, k, avg[k]);
- }
- average = 0;
- for (i = 0; i < channels; i++)
- average += avg[i];
- average /= channels;
- DBG(DBG_info, "%s: average = %d\n", __func__, average);
- return average;
-}
-
-
void CommandSetGl124::offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor,
Genesys_Register_Set& regs) const
{
- DBG_HELPER(dbg);
- unsigned channels;
- int pass = 0, avg, total_size;
- int topavg, bottomavg, lines;
- int top, bottom, black_pixels, pixels;
-
- // no gain nor offset for TI AFE
- uint8_t reg0a = dev->interface->read_register(REG_0x0A);
- if (((reg0a & REG_0x0A_SIFSEL) >> REG_0x0AS_SIFSEL) == 3) {
- return;
- }
-
- /* offset calibration is always done in color mode */
- channels = 3;
- dev->calib_pixels = sensor.sensor_pixels;
- lines=1;
- pixels = (sensor.sensor_pixels * sensor.optical_res) / sensor.optical_res;
- black_pixels = (sensor.black_pixels * sensor.optical_res) / sensor.optical_res;
- DBG(DBG_io2, "%s: black_pixels=%d\n", __func__, black_pixels);
-
- ScanSession session;
- session.params.xres = sensor.optical_res;
- session.params.yres = sensor.optical_res;
- session.params.startx = 0;
- session.params.starty = 0;
- session.params.pixels = pixels;
- session.params.lines = lines;
- session.params.depth = 8;
- session.params.channels = channels;
- session.params.scan_method = dev->settings.scan_method;
- session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS;
- session.params.color_filter = dev->settings.color_filter;
- session.params.flags = ScanFlag::DISABLE_SHADING |
- ScanFlag::DISABLE_GAMMA |
- ScanFlag::SINGLE_LINE |
- ScanFlag::IGNORE_LINE_DISTANCE;
- compute_session(dev, session, sensor);
-
- init_regs_for_scan_session(dev, sensor, &regs, session);
-
- sanei_genesys_set_motor_power(regs, false);
-
- /* allocate memory for scans */
- total_size = pixels * channels * lines * (session.params.depth / 8);
-
- std::vector<uint8_t> first_line(total_size);
- std::vector<uint8_t> second_line(total_size);
-
- /* init gain */
- dev->frontend.set_gain(0, 0);
- dev->frontend.set_gain(1, 0);
- dev->frontend.set_gain(2, 0);
-
- /* scan with no move */
- bottom = 10;
- dev->frontend.set_offset(0, bottom);
- dev->frontend.set_offset(1, bottom);
- dev->frontend.set_offset(2, bottom);
-
- set_fe(dev, sensor, AFE_SET);
- dev->interface->write_registers(regs);
- DBG(DBG_info, "%s: starting first line reading\n", __func__);
- begin_scan(dev, sensor, &regs, true);
-
- if (is_testing_mode()) {
- dev->interface->test_checkpoint("offset_calibration");
- return;
- }
-
- sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size);
- if (DBG_LEVEL >= DBG_data)
- {
- char title[30];
- std::snprintf(title, 30, "gl124_offset%03d.pnm", bottom);
- sanei_genesys_write_pnm_file(title, first_line.data(), session.params.depth,
- channels, pixels, lines);
- }
-
- bottomavg = dark_average(first_line.data(), pixels, lines, channels, black_pixels);
- DBG(DBG_io2, "%s: bottom avg=%d\n", __func__, bottomavg);
-
- /* now top value */
- top = 255;
- dev->frontend.set_offset(0, top);
- dev->frontend.set_offset(1, top);
- dev->frontend.set_offset(2, top);
- set_fe(dev, sensor, AFE_SET);
- dev->interface->write_registers(regs);
- DBG(DBG_info, "%s: starting second line reading\n", __func__);
- begin_scan(dev, sensor, &regs, true);
- sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size);
-
- topavg = dark_average(second_line.data(), pixels, lines, channels, black_pixels);
- DBG(DBG_io2, "%s: top avg=%d\n", __func__, topavg);
-
- /* loop until acceptable level */
- while ((pass < 32) && (top - bottom > 1))
- {
- pass++;
-
- /* settings for new scan */
- dev->frontend.set_offset(0, (top + bottom) / 2);
- dev->frontend.set_offset(1, (top + bottom) / 2);
- dev->frontend.set_offset(2, (top + bottom) / 2);
-
- // scan with no move
- set_fe(dev, sensor, AFE_SET);
- dev->interface->write_registers(regs);
- DBG(DBG_info, "%s: starting second line reading\n", __func__);
- begin_scan(dev, sensor, &regs, true);
- sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size);
-
- if (DBG_LEVEL >= DBG_data)
- {
- char title[30];
- std::snprintf(title, 30, "gl124_offset%03d.pnm", dev->frontend.get_offset(1));
- sanei_genesys_write_pnm_file(title, second_line.data(), session.params.depth,
- channels, pixels, lines);
- }
-
- avg = dark_average(second_line.data(), pixels, lines, channels, black_pixels);
- DBG(DBG_info, "%s: avg=%d offset=%d\n", __func__, avg, dev->frontend.get_offset(1));
-
- /* compute new boundaries */
- if (topavg == avg)
- {
- topavg = avg;
- top = dev->frontend.get_offset(1);
- }
- else
- {
- bottomavg = avg;
- bottom = dev->frontend.get_offset(1);
- }
- }
- DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__,
- dev->frontend.get_offset(0),
- dev->frontend.get_offset(1),
- dev->frontend.get_offset(2));
+ scanner_offset_calibration(*dev, sensor, regs);
}
-
-/* alternative coarse gain calibration
- this on uses the settings from offset_calibration and
- uses only one scanline
- */
-/*
- with offset and coarse calibration we only want to get our input range into
- a reasonable shape. the fine calibration of the upper and lower bounds will
- be done with shading.
- */
void CommandSetGl124::coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor,
Genesys_Register_Set& regs, int dpi) const
{
- DBG_HELPER_ARGS(dbg, "dpi = %d", dpi);
- int pixels;
- int total_size;
- int i, j, channels;
- int max[3];
- float gain[3],coeff;
- int val, code, lines;
-
- // no gain nor offset for TI AFE
- uint8_t reg0a = dev->interface->read_register(REG_0x0A);
- if (((reg0a & REG_0x0A_SIFSEL) >> REG_0x0AS_SIFSEL) == 3) {
- return;
- }
-
- /* coarse gain calibration is always done in color mode */
- channels = 3;
-
- if(dev->settings.xres<sensor.optical_res)
- {
- coeff = 0.9f;
- } else {
- coeff = 1.0f;
- }
- lines=10;
- pixels = (sensor.sensor_pixels * sensor.optical_res) / sensor.optical_res;
-
- ScanSession session;
- session.params.xres = sensor.optical_res;
- session.params.yres = sensor.optical_res;
- session.params.startx = 0;
- session.params.starty = 0;
- session.params.pixels = pixels;
- session.params.lines = lines;
- session.params.depth = 8;
- session.params.channels = channels;
- session.params.scan_method = dev->settings.scan_method;
- session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS;
- session.params.color_filter = dev->settings.color_filter;
- session.params.flags = ScanFlag::DISABLE_SHADING |
- ScanFlag::DISABLE_GAMMA |
- ScanFlag::SINGLE_LINE |
- ScanFlag::IGNORE_LINE_DISTANCE;
- compute_session(dev, session, sensor);
-
- try {
- init_regs_for_scan_session(dev, sensor, &regs, session);
- } catch (...) {
- catch_all_exceptions(__func__, [&](){ sanei_genesys_set_motor_power(regs, false); });
- throw;
- }
-
- sanei_genesys_set_motor_power(regs, false);
-
- dev->interface->write_registers(regs);
-
- total_size = pixels * channels * (16 / session.params.depth) * lines;
-
- std::vector<uint8_t> line(total_size);
-
- set_fe(dev, sensor, AFE_SET);
- begin_scan(dev, sensor, &regs, true);
-
- if (is_testing_mode()) {
- dev->interface->test_checkpoint("coarse_gain_calibration");
- scanner_stop_action(*dev);
- move_back_home(dev, true);
- return;
- }
-
- sanei_genesys_read_data_from_scanner(dev, line.data(), total_size);
-
- if (DBG_LEVEL >= DBG_data) {
- sanei_genesys_write_pnm_file("gl124_gain.pnm", line.data(), session.params.depth,
- channels, pixels, lines);
- }
-
- /* average value on each channel */
- for (j = 0; j < channels; j++)
- {
- max[j] = 0;
- for (i = pixels/4; i < (pixels*3/4); i++)
- {
- if (dev->model->is_cis) {
- val = line[i + j * pixels];
- } else {
- val = line[i * channels + j];
- }
-
- max[j] += val;
- }
- max[j] = max[j] / (pixels/2);
-
- gain[j] = (static_cast<float>(sensor.gain_white_ref) * coeff) / max[j];
-
- /* turn logical gain value into gain code, checking for overflow */
- code = static_cast<int>(283 - 208 / gain[j]);
- if (code > 255)
- code = 255;
- else if (code < 0)
- code = 0;
- dev->frontend.set_gain(j, code);
-
- DBG(DBG_proc, "%s: channel %d, max=%d, gain = %f, setting:%d\n", __func__, j, max[j],
- gain[j], dev->frontend.get_gain(j));
- }
-
- if (dev->model->is_cis) {
- uint8_t gain0 = dev->frontend.get_gain(0);
- if (gain0 > dev->frontend.get_gain(1)) {
- gain0 = dev->frontend.get_gain(1);
- }
- if (gain0 > dev->frontend.get_gain(2)) {
- gain0 = dev->frontend.get_gain(2);
- }
- dev->frontend.set_gain(0, gain0);
- dev->frontend.set_gain(1, gain0);
- dev->frontend.set_gain(2, gain0);
- }
-
- if (channels == 1) {
- dev->frontend.set_gain(0, dev->frontend.get_gain(1));
- dev->frontend.set_gain(2, dev->frontend.get_gain(1));
- }
-
- scanner_stop_action(*dev);
-
- move_back_home(dev, true);
+ scanner_coarse_gain_calibration(*dev, sensor, regs, dpi);
}
// wait for lamp warmup by scanning the same line until difference
// between 2 scans is below a threshold
void CommandSetGl124::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Sensor& sensor,
- Genesys_Register_Set* reg, int* channels,
- int* total_size) const
+ Genesys_Register_Set* reg) const
{
DBG_HELPER(dbg);
- int num_pixels;
-
- *channels=3;
*reg = dev->reg;
+ auto flags = ScanFlag::DISABLE_SHADING |
+ ScanFlag::DISABLE_GAMMA |
+ ScanFlag::SINGLE_LINE |
+ ScanFlag::IGNORE_STAGGER_OFFSET |
+ ScanFlag::IGNORE_COLOR_OFFSET;
+ if (dev->settings.scan_method == ScanMethod::TRANSPARENCY ||
+ dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED)
+ {
+ flags |= ScanFlag::USE_XPA;
+ }
+
ScanSession session;
- session.params.xres = sensor.optical_res;
+ session.params.xres = sensor.full_resolution;
session.params.yres = dev->motor.base_ydpi;
- session.params.startx = sensor.sensor_pixels / 4;
+ session.params.startx = dev->model->x_size_calib_mm * sensor.full_resolution / MM_PER_INCH / 4;
session.params.starty = 0;
- session.params.pixels = sensor.sensor_pixels / 2;
+ session.params.pixels = dev->model->x_size_calib_mm * sensor.full_resolution / MM_PER_INCH / 2;
session.params.lines = 1;
- session.params.depth = 8;
- session.params.channels = *channels;
+ session.params.depth = dev->model->bpp_color_values.front();
+ session.params.channels = 3;
session.params.scan_method = dev->settings.scan_method;
session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS;
session.params.color_filter = dev->settings.color_filter;
- session.params.flags = ScanFlag::DISABLE_SHADING |
- ScanFlag::DISABLE_GAMMA |
- ScanFlag::SINGLE_LINE |
- ScanFlag::IGNORE_LINE_DISTANCE;
+ session.params.flags = flags;
+
compute_session(dev, session, sensor);
init_regs_for_scan_session(dev, sensor, reg, session);
- num_pixels = session.output_pixels;
-
- *total_size = num_pixels * 3 * 1; /* colors * bytes_per_color * scan lines */
-
sanei_genesys_set_motor_power(*reg, false);
- dev->interface->write_registers(*reg);
}
/** @brief default GPIO values
@@ -2049,64 +1248,8 @@ static void gl124_init_gpio(Genesys_Device* dev)
static void gl124_init_memory_layout(Genesys_Device* dev)
{
DBG_HELPER(dbg);
- int idx = 0;
- /* point to per model memory layout */
- if (dev->model->model_id == ModelId::CANON_LIDE_110 ||
- dev->model->model_id == ModelId::CANON_LIDE_120)
- {
- idx = 0;
- }
- else
- { /* canon LiDE 210 and 220 case */
- idx = 1;
- }
-
- /* setup base address for shading data. */
- /* values must be multiplied by 8192=0x4000 to give address on AHB */
- /* R-Channel shading bank0 address setting for CIS */
- dev->interface->write_register(0xd0, layouts[idx].rd0);
- /* G-Channel shading bank0 address setting for CIS */
- dev->interface->write_register(0xd1, layouts[idx].rd1);
- /* B-Channel shading bank0 address setting for CIS */
- dev->interface->write_register(0xd2, layouts[idx].rd2);
-
- /* setup base address for scanned data. */
- /* values must be multiplied by 1024*2=0x0800 to give address on AHB */
- /* R-Channel ODD image buffer 0x0124->0x92000 */
- /* size for each buffer is 0x16d*1k word */
- dev->interface->write_register(0xe0, layouts[idx].re0);
- dev->interface->write_register(0xe1, layouts[idx].re1);
- /* R-Channel ODD image buffer end-address 0x0291->0x148800 => size=0xB6800*/
- dev->interface->write_register(0xe2, layouts[idx].re2);
- dev->interface->write_register(0xe3, layouts[idx].re3);
-
- /* R-Channel EVEN image buffer 0x0292 */
- dev->interface->write_register(0xe4, layouts[idx].re4);
- dev->interface->write_register(0xe5, layouts[idx].re5);
- /* R-Channel EVEN image buffer end-address 0x03ff*/
- dev->interface->write_register(0xe6, layouts[idx].re6);
- dev->interface->write_register(0xe7, layouts[idx].re7);
-
- /* same for green, since CIS, same addresses */
- dev->interface->write_register(0xe8, layouts[idx].re0);
- dev->interface->write_register(0xe9, layouts[idx].re1);
- dev->interface->write_register(0xea, layouts[idx].re2);
- dev->interface->write_register(0xeb, layouts[idx].re3);
- dev->interface->write_register(0xec, layouts[idx].re4);
- dev->interface->write_register(0xed, layouts[idx].re5);
- dev->interface->write_register(0xee, layouts[idx].re6);
- dev->interface->write_register(0xef, layouts[idx].re7);
-
-/* same for blue, since CIS, same addresses */
- dev->interface->write_register(0xf0, layouts[idx].re0);
- dev->interface->write_register(0xf1, layouts[idx].re1);
- dev->interface->write_register(0xf2, layouts[idx].re2);
- dev->interface->write_register(0xf3, layouts[idx].re3);
- dev->interface->write_register(0xf4, layouts[idx].re4);
- dev->interface->write_register(0xf5, layouts[idx].re5);
- dev->interface->write_register(0xf6, layouts[idx].re6);
- dev->interface->write_register(0xf7, layouts[idx].re7);
+ apply_reg_settings_to_device_write_only(*dev, dev->memory_layout.regs);
}
/**
@@ -2118,7 +1261,7 @@ void CommandSetGl124::init(Genesys_Device* dev) const
DBG_INIT ();
DBG_HELPER(dbg);
- sanei_genesys_asic_init(dev, 0);
+ sanei_genesys_asic_init(dev);
}
@@ -2244,26 +1387,5 @@ void CommandSetGl124::eject_document(Genesys_Device* dev) const
throw SaneException("not implemented");
}
-void CommandSetGl124::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor,
- bool forward, bool black) const
-{
- (void) dev;
- (void) sensor;
- (void) forward;
- (void) black;
- throw SaneException("not implemented");
-}
-
-void CommandSetGl124::move_to_ta(Genesys_Device* dev) const
-{
- (void) dev;
- throw SaneException("not implemented");
-}
-
-std::unique_ptr<CommandSet> create_gl124_cmd_set()
-{
- return std::unique_ptr<CommandSet>(new CommandSetGl124{});
-}
-
} // namespace gl124
} // namespace genesys