diff --git a/backend/Makefile.am b/backend/Makefile.am index 17e44377a..bd44f88d6 100644 --- a/backend/Makefile.am +++ b/backend/Makefile.am @@ -513,6 +513,7 @@ libgenesys_la_SOURCES = genesys/genesys.cpp genesys/genesys.h \ genesys/sensor.h genesys/sensor.cpp \ genesys/settings.h genesys/settings.cpp \ genesys/serialize.h \ + genesys/static_init.h genesys/static_init.cpp \ genesys/tables_frontend.cpp \ genesys/tables_gpo.cpp \ genesys/tables_model.cpp \ diff --git a/backend/genesys/enums.cpp b/backend/genesys/enums.cpp index 66238648c..f515cfdd0 100644 --- a/backend/genesys/enums.cpp +++ b/backend/genesys/enums.cpp @@ -45,6 +45,7 @@ #include "enums.h" #include "genesys.h" +#include namespace genesys { @@ -108,4 +109,23 @@ std::ostream& operator<<(std::ostream& out, ColorFilter mode) return out; } +std::ostream& operator<<(std::ostream& out, StepType type) +{ + switch (type) { + case StepType::FULL: out << "1/1"; break; + case StepType::HALF: out << "1/2"; break; + case StepType::QUARTER: out << "1/4"; break; + case StepType::EIGHTH: out << "1/8"; break; + default: out << static_cast(type); break; + } + return out; +} + +std::ostream& operator<<(std::ostream& out, ScanFlag flags) +{ + StreamStateSaver state_saver{out}; + out << "0x" << std::hex << static_cast(flags); + return out; +} + } // namespace genesys diff --git a/backend/genesys/enums.h b/backend/genesys/enums.h index 81fc31d16..15a5e2fa9 100644 --- a/backend/genesys/enums.h +++ b/backend/genesys/enums.h @@ -379,6 +379,25 @@ enum class StepType : unsigned EIGHTH = 3, }; +std::ostream& operator<<(std::ostream& out, StepType type); + +inline bool operator<(StepType lhs, StepType rhs) +{ + return static_cast(lhs) < static_cast(rhs); +} +inline bool operator<=(StepType lhs, StepType rhs) +{ + return static_cast(lhs) <= static_cast(rhs); +} +inline bool operator>(StepType lhs, StepType rhs) +{ + return static_cast(lhs) > static_cast(rhs); +} +inline bool operator>=(StepType lhs, StepType rhs) +{ + return static_cast(lhs) >= static_cast(rhs); +} + enum class AsicType : unsigned { UNKNOWN = 0, @@ -391,6 +410,59 @@ enum class AsicType : unsigned GL124, }; + +enum class ScanFlag : unsigned +{ + NONE = 0, + SINGLE_LINE = 1 << 0, + DISABLE_SHADING = 1 << 1, + DISABLE_GAMMA = 1 << 2, + DISABLE_BUFFER_FULL_MOVE = 1 << 3, + IGNORE_LINE_DISTANCE = 1 << 4, + DISABLE_LAMP = 1 << 5, + CALIBRATION = 1 << 6, + FEEDING = 1 << 7, + USE_XPA = 1 << 8, + ENABLE_LEDADD = 1 << 9, + USE_XCORRECTION = 1 << 10, +}; + +inline ScanFlag operator|(ScanFlag left, ScanFlag right) +{ + return static_cast(static_cast(left) | static_cast(right)); +} + +inline ScanFlag& operator|=(ScanFlag& left, ScanFlag right) +{ + left = left | right; + return left; +} + +inline ScanFlag operator&(ScanFlag left, ScanFlag right) +{ + return static_cast(static_cast(left) & static_cast(right)); +} + +inline bool has_flag(ScanFlag flags, ScanFlag which) +{ + return (flags & which) == which; +} + +inline void serialize(std::istream& str, ScanFlag& x) +{ + unsigned value; + serialize(str, value); + x = static_cast(value); +} + +inline void serialize(std::ostream& str, ScanFlag& x) +{ + unsigned value = static_cast(x); + serialize(str, value); +} + +std::ostream& operator<<(std::ostream& out, ScanFlag flags); + } // namespace genesys #endif // BACKEND_GENESYS_ENUMS_H diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index b990eeb60..3634ca033 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -434,14 +434,14 @@ SANE_Int sanei_genesys_generate_slope_table(std::vector& slope_table, * @return Time for acceleration * @note all times in pixel time */ -SANE_Int sanei_genesys_create_slope_table3(Genesys_Device * dev, +SANE_Int sanei_genesys_create_slope_table3(const Genesys_Motor& motor, std::vector& slope_table, int max_step, unsigned int use_steps, - int step_type, + StepType step_type, int exposure_time, - double yres, - unsigned int *used_steps, + unsigned yres, + unsigned int *used_steps, unsigned int *final_exposure) { unsigned int sum_time = 0; @@ -450,26 +450,21 @@ SANE_Int sanei_genesys_create_slope_table3(Genesys_Device * dev, unsigned int vstart; unsigned int vfinal; - DBG(DBG_proc, "%s: step_type = %d, exposure_time = %d, yres = %g\n", __func__, - step_type, exposure_time, yres); + DBG(DBG_proc, "%s: step_type = %d, exposure_time = %d, yres = %d\n", __func__, + static_cast(step_type), exposure_time, yres); /* final speed */ - vtarget = static_cast((exposure_time * yres) / dev->motor.base_ydpi); + vtarget = (exposure_time * yres) / motor.base_ydpi; - vstart = dev->motor.slopes[step_type].maximum_start_speed; - vend = dev->motor.slopes[step_type].maximum_speed; + const auto& slope = motor.get_slope(step_type).legacy(); - vtarget >>= step_type; - if (vtarget > 65535) - vtarget = 65535; + unsigned u_step_type = static_cast(step_type); + vstart = slope.maximum_start_speed; + vend = slope.maximum_speed; - vstart >>= step_type; - if (vstart > 65535) - vstart = 65535; - - vend >>= step_type; - if (vend > 65535) - vend = 65535; + vtarget = std::min(vtarget >> u_step_type, 65535u); + vstart = std::min(vstart >> u_step_type, 65535u); + vend = std::min(vend >> u_step_type, 65535u); sum_time = sanei_genesys_generate_slope_table (slope_table, max_step, @@ -477,295 +472,13 @@ SANE_Int sanei_genesys_create_slope_table3(Genesys_Device * dev, vtarget, vstart, vend, - dev->motor.slopes[step_type].minimum_steps << step_type, - dev->motor.slopes[step_type].g, + slope.minimum_steps << u_step_type, + slope.g, used_steps, &vfinal); if (final_exposure) { - *final_exposure = static_cast((vfinal * dev->motor.base_ydpi) / yres); - } - - DBG(DBG_proc, "%s: returns sum_time=%d, completed\n", __func__, sum_time); - - return sum_time; -} - - -/* alternate slope table creation function */ -/* the hardcoded values (g and vstart) will go in a motor struct */ -SANE_Int genesys_create_slope_table2(Genesys_Device* dev, std::vector& slope_table, - int steps, - int step_type, int exposure_time, - bool same_speed, double yres) -{ - double t, g; - SANE_Int sum = 0; - int vstart, vend; - int i; - - DBG(DBG_proc, "%s: %d steps, step_type = %d, " - "exposure_time = %d, same_speed = %d, yres = %.2f\n", __func__, steps, - step_type, exposure_time, same_speed, yres); - - /* start speed */ - if (dev->model->motor_id == MotorId::MD_5345) { - if (yres < dev->motor.base_ydpi / 6) - vstart = 2500; - else - vstart = 2000; - } - else - { - if (steps == 2) { - vstart = exposure_time; - } else if (steps == 3) { - vstart = 2 * exposure_time; - } else if (steps == 4) { - vstart = static_cast(1.5 * exposure_time); - } else if (steps == 120) { - vstart = static_cast(1.81674 * exposure_time); - } else { - vstart = exposure_time; - } - } - - /* final speed */ - vend = static_cast((exposure_time * yres) / (dev->motor.base_ydpi * (1 << step_type))); - - /* - type=1 : full - type=2 : half - type=4 : quarter - vend * type * base_ydpi / exposure = yres - */ - - /* acceleration */ - switch (steps) - { - case 255: - /* test for special case: fast moving slope */ - /* todo: a 'fast' boolean parameter should be better */ - if (vstart == 2000) - g = 0.2013; - else - g = 0.1677; - break; - case 120: - g = 0.5; - break; - case 67: - g = 0.5; - break; - case 64: - g = 0.2555; - break; - case 44: - g = 0.5; - break; - case 4: - g = 0.5; - break; - case 3: - g = 1; - break; - case 2: - vstart = vend; - g = 1; - break; - default: - g = 0.2635; - } - - /* if same speed, no 'g' */ - sum = 0; - if (same_speed) - { - for (i = 0; i < 255; i++) - { - slope_table[i] = vend; - sum += slope_table[i]; - DBG (DBG_io, "slope_table[%3d] = %5d\n", i, slope_table[i]); - } - } - else - { - for (i = 0; i < steps; i++) - { - t = std::pow(static_cast(i) / static_cast(steps - 1), g); - slope_table[i] = static_cast(vstart * (1 - t) + t * vend); - DBG (DBG_io, "slope_table[%3d] = %5d\n", i, slope_table[i]); - sum += slope_table[i]; - } - for (i = steps; i < 255; i++) - { - slope_table[i] = vend; - DBG (DBG_io, "slope_table[%3d] = %5d\n", i, slope_table[i]); - sum += slope_table[i]; - } - } - - DBG(DBG_proc, "%s: returns sum=%d, completed\n", __func__, sum); - - return sum; -} - -/* Generate slope table for motor movement */ -/* todo: check details */ -SANE_Int sanei_genesys_create_slope_table(Genesys_Device * dev, std::vector& slope_table, - int steps, int step_type, int exposure_time, - bool same_speed, double yres) -{ - double t; - double start_speed; - double g; - uint32_t time_period; - int sum_time = 0; - int i, divider; - int same_step; - - if (dev->model->motor_id == MotorId::MD_5345 || - dev->model->motor_id == MotorId::HP2300 || - dev->model->motor_id == MotorId::HP2400) - { - return genesys_create_slope_table2(dev, slope_table, steps, step_type, exposure_time, - same_speed, yres); - } - - DBG(DBG_proc, "%s: %d steps, step_type = %d, exposure_time = %d, same_speed =%d\n", __func__, - steps, step_type, exposure_time, same_speed); - DBG(DBG_proc, "%s: yres = %.2f\n", __func__, yres); - - g = 0.6; - start_speed = 0.01; - same_step = 4; - divider = 1 << step_type; - - time_period = static_cast(yres * exposure_time / - dev->motor.base_ydpi /*MOTOR_GEAR */ ); - if ((time_period < 2000) && (same_speed)) - same_speed = false; - - time_period = time_period / divider; - - if (same_speed) - { - for (i = 0; i < steps; i++) - { - slope_table[i] = static_cast(time_period); - sum_time += time_period; - - DBG (DBG_io, "slope_table[%d] = %d\n", i, time_period); - } - DBG(DBG_info, "%s: returns sum_time=%d, completed\n", __func__, sum_time); - return sum_time; - } - - if (time_period > MOTOR_SPEED_MAX * 5) - { - g = 1.0; - start_speed = 0.05; - same_step = 2; - } - else if (time_period > MOTOR_SPEED_MAX * 4) - { - g = 0.8; - start_speed = 0.04; - same_step = 2; - } - else if (time_period > MOTOR_SPEED_MAX * 3) - { - g = 0.7; - start_speed = 0.03; - same_step = 2; - } - else if (time_period > MOTOR_SPEED_MAX * 2) - { - g = 0.6; - start_speed = 0.02; - same_step = 3; - } - - if (dev->model->motor_id == MotorId::ST24) { - steps = 255; - switch (static_cast(yres)) - { - case 2400: - g = 0.1672; - start_speed = 1.09; - break; - case 1200: - g = 1; - start_speed = 6.4; - break; - case 600: - g = 0.1672; - start_speed = 1.09; - break; - case 400: - g = 0.2005; - start_speed = 20.0 / 3.0 /*7.5 */ ; - break; - case 300: - g = 0.253; - start_speed = 2.182; - break; - case 150: - g = 0.253; - start_speed = 4.367; - break; - default: - g = 0.262; - start_speed = 7.29; - } - same_step = 1; - } - - if (steps <= same_step) - { - time_period = static_cast(yres * exposure_time / - dev->motor.base_ydpi /*MOTOR_GEAR */ ); - time_period = time_period / divider; - - if (time_period > 65535) - time_period = 65535; - - for (i = 0; i < same_step; i++) - { - slope_table[i] = static_cast(time_period); - sum_time += time_period; - - DBG (DBG_io, "slope_table[%d] = %d\n", i, time_period); - } - - DBG(DBG_proc, "%s: returns sum_time=%d, completed\n", __func__, sum_time); - return sum_time; - } - - for (i = 0; i < steps; i++) - { - double j = static_cast(i) - same_step + 1; /* start from 1/16 speed */ - - if (j <= 0) { - t = 0; - } else { - t = std::pow(j / (steps - same_step), g); - } - - // time required for full steps - time_period = static_cast(yres * exposure_time / - dev->motor.base_ydpi /*MOTOR_GEAR */ * - (start_speed + (1 - start_speed) * t)); - - time_period = time_period / divider; - if (time_period > 65535) { - time_period = 65535; - } - - slope_table[i] = static_cast(time_period); - sum_time += time_period; - - DBG (DBG_io, "slope_table[%d] = %d\n", i, slope_table[i]); + *final_exposure = (vfinal * motor.base_ydpi) / yres; } DBG(DBG_proc, "%s: returns sum_time=%d, completed\n", __func__, sum_time); @@ -841,12 +554,11 @@ void sanei_genesys_create_default_gamma_table(Genesys_Device* dev, Note: The enhance option of the scanners does _not_ help. It only halves the amount of pixels transfered. */ -SANE_Int -sanei_genesys_exposure_time2 (Genesys_Device * dev, float ydpi, - int step_type, int endpixel, int exposure_by_led) +SANE_Int sanei_genesys_exposure_time2(Genesys_Device * dev, float ydpi, + StepType step_type, int endpixel, int exposure_by_led) { int exposure_by_ccd = endpixel + 32; - int exposure_by_motor = static_cast((dev->motor.slopes[step_type].maximum_speed * + int exposure_by_motor = static_cast((dev->motor.get_slope(step_type).legacy().maximum_speed * dev->motor.base_ydpi) / ydpi); int exposure = exposure_by_ccd; @@ -858,7 +570,8 @@ sanei_genesys_exposure_time2 (Genesys_Device * dev, float ydpi, exposure = exposure_by_led; DBG(DBG_info, "%s: ydpi=%d, step=%d, endpixel=%d led=%d => exposure=%d\n", __func__, - static_cast(ydpi), step_type, endpixel, exposure_by_led, exposure); + static_cast(ydpi), static_cast(step_type), endpixel, + exposure_by_led, exposure); return exposure; } @@ -4710,6 +4423,7 @@ void sane_init_impl(SANE_Int * version_code, SANE_Auth_Callback authorize) genesys_init_frontend_tables(); genesys_init_gpo_tables(); genesys_init_motor_tables(); + genesys_init_motor_profile_tables(); genesys_init_usb_device_tables(); diff --git a/backend/genesys/gl124.cpp b/backend/genesys/gl124.cpp index 3c404aeaf..5b0bd208e 100644 --- a/backend/genesys/gl124.cpp +++ b/backend/genesys/gl124.cpp @@ -397,6 +397,9 @@ static void gl124_send_slope_table(Genesys_Device* dev, int table_nr, 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()); } @@ -481,9 +484,9 @@ 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, unsigned int scan_exposure_time, unsigned scan_yres, - StepType step_type, unsigned int scan_lines, unsigned int scan_dummy, unsigned int feed_steps, @@ -493,9 +496,7 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev, DBG_HELPER(dbg); int use_fast_fed; unsigned int lincnt, fast_dpi; - std::vector scan_table; - std::vector fast_table; - int scan_steps,fast_steps,factor; + int factor; unsigned int feedl,dist; uint32_t z1, z2; unsigned yres; @@ -504,8 +505,8 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev, DBG(DBG_info, "%s : scan_exposure_time=%d, scan_yres=%d, step_type=%d, scan_lines=%d, " "scan_dummy=%d, feed_steps=%d, scan_mode=%d, flags=%x\n", __func__, scan_exposure_time, - scan_yres, static_cast(step_type), scan_lines, scan_dummy, feed_steps, - static_cast(scan_mode), flags); + scan_yres, static_cast(motor_profile.step_type), scan_lines, scan_dummy, + feed_steps, static_cast(scan_mode), flags); /* we never use fast fed since we do manual feed for the scans */ use_fast_fed=0; @@ -581,19 +582,12 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev, reg->set16(REG_SCANFED, 4); /* scan and backtracking slope table */ - sanei_genesys_slope_table(scan_table, - &scan_steps, - yres, - scan_exposure_time, - dev->motor.base_ydpi, - step_type, - factor, - dev->model->motor_id, - gl124_motor_profiles); - gl124_send_slope_table(dev, SCAN_TABLE, scan_table, scan_steps); - gl124_send_slope_table(dev, BACKTRACK_TABLE, scan_table, scan_steps); + auto scan_table = sanei_genesys_slope_table(yres, scan_exposure_time, + dev->motor.base_ydpi, factor, motor_profile); + gl124_send_slope_table(dev, SCAN_TABLE, scan_table.table, scan_table.scan_steps); + gl124_send_slope_table(dev, BACKTRACK_TABLE, scan_table.table, scan_table.scan_steps); - reg->set16(REG_STEPNO, scan_steps); + reg->set16(REG_STEPNO, scan_table.scan_steps); /* fast table */ fast_dpi=yres; @@ -604,32 +598,25 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev, fast_dpi*=3; } */ - sanei_genesys_slope_table(fast_table, - &fast_steps, - fast_dpi, - scan_exposure_time, - dev->motor.base_ydpi, - step_type, - factor, - dev->model->motor_id, - gl124_motor_profiles); - gl124_send_slope_table(dev, STOP_TABLE, fast_table, fast_steps); - gl124_send_slope_table(dev, FAST_TABLE, fast_table, fast_steps); + auto fast_table = sanei_genesys_slope_table(fast_dpi, scan_exposure_time, dev->motor.base_ydpi, + factor, motor_profile); + gl124_send_slope_table(dev, STOP_TABLE, fast_table.table, fast_table.scan_steps); + gl124_send_slope_table(dev, FAST_TABLE, fast_table.table, fast_table.scan_steps); - reg->set16(REG_FASTNO, fast_steps); - reg->set16(REG_FSHDEC, fast_steps); - reg->set16(REG_FMOVNO, fast_steps); + reg->set16(REG_FASTNO, fast_table.scan_steps); + reg->set16(REG_FSHDEC, fast_table.scan_steps); + reg->set16(REG_FMOVNO, fast_table.scan_steps); /* substract acceleration distance from feedl */ feedl=feed_steps; - feedl <<= static_cast(step_type); + feedl <<= static_cast(motor_profile.step_type); - dist = scan_steps; - if (flags & MOTOR_FLAG_FEED) - dist *=2; - if (use_fast_fed) - { - dist += fast_steps*2; + dist = scan_table.scan_steps; + if (flags & MOTOR_FLAG_FEED) { + dist *= 2; + } + if (use_fast_fed) { + dist += fast_table.scan_steps * 2; } DBG (DBG_io2, "%s: acceleration distance=%d\n", __func__, dist); @@ -644,12 +631,12 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev, DBG (DBG_io, "%s: feedl=%d\n", __func__, feedl); /* doesn't seem to matter that much */ - sanei_genesys_calculate_zmod (use_fast_fed, + sanei_genesys_calculate_zmod(use_fast_fed, scan_exposure_time, - scan_table, - scan_steps, + scan_table.table, + scan_table.scan_steps, feedl, - scan_steps, + scan_table.scan_steps, &z1, &z2); @@ -661,10 +648,10 @@ static void gl124_init_motor_regs_scan(Genesys_Device* dev, /* LINESEL */ reg->set8_mask(REG_0x1D, linesel, REG_0x1D_LINESEL); - reg->set8(REG_0xA0, (static_cast(step_type) << REG_0xA0S_STEPSEL) | - (static_cast(step_type) << REG_0xA0S_FSTPSEL)); + reg->set8(REG_0xA0, (static_cast(motor_profile.step_type) << REG_0xA0S_STEPSEL) | + (static_cast(motor_profile.step_type) << REG_0xA0S_FSTPSEL)); - reg->set16(REG_FMOVDEC, fast_steps); + reg->set16(REG_FMOVDEC, fast_table.scan_steps); } @@ -769,7 +756,7 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens /* enable shading */ r = sanei_genesys_get_address (reg, REG_0x01); r->value &= ~REG_0x01_SCAN; - if ((session.params.flags & SCAN_FLAG_DISABLE_SHADING) || + if (has_flag(session.params.flags, ScanFlag::DISABLE_SHADING) || (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) { r->value &= ~REG_0x01_DVDSET; @@ -790,7 +777,7 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens } sanei_genesys_set_lamp_power(dev, sensor, *reg, - !(session.params.flags & SCAN_FLAG_DISABLE_LAMP)); + !has_flag(session.params.flags, ScanFlag::DISABLE_LAMP)); // BW threshold dev->interface->write_register(REG_0x114, dev->settings.threshold); @@ -907,7 +894,6 @@ static void gl124_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens int dummy = 0; int slope_dpi = 0; - StepType scan_step_type = StepType::HALF; /* cis color scan is effectively a gray scan with 3 gray lines per color line and a FILTER of 0 */ if (dev->model->is_cis) { @@ -916,20 +902,18 @@ static void gl124_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens slope_dpi = session.params.yres; } - if(session.params.flags & SCAN_FLAG_FEEDING) { + if (has_flag(session.params.flags, ScanFlag::FEEDING)) { exposure_time = 2304; - scan_step_type = StepType::FULL; - } - else - { + } else { exposure_time = get_sensor_profile(dev->model->asic_type, sensor, session.params.xres, session.ccd_size_divisor).exposure_lperiod; - scan_step_type = sanei_genesys_compute_step_type(gl124_motor_profiles, - dev->model->motor_id, exposure_time); } + const auto& motor_profile = sanei_genesys_get_motor_profile(*gl124_motor_profiles, + dev->model->motor_id, + exposure_time); DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); - DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, static_cast(scan_step_type)); + DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, static_cast(motor_profile.step_type)); /* we enable true gray for cis scanners only, and just when doing * scan since color calibration is OK for this mode @@ -943,13 +927,13 @@ static void gl124_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens DBG(DBG_info, "%s: move=%d steps\n", __func__, move); mflags = 0; - if (session.params.flags & SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE) { + if (has_flag(session.params.flags, ScanFlag::DISABLE_BUFFER_FULL_MOVE)) { mflags |= MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE; } - if (session.params.flags & SCAN_FLAG_FEEDING) { + if (has_flag(session.params.flags, ScanFlag::FEEDING)) { mflags |= MOTOR_FLAG_FEED; } - gl124_init_motor_regs_scan(dev, sensor, reg, exposure_time, slope_dpi, scan_step_type, + 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); @@ -997,7 +981,7 @@ ScanSession CommandSetGl124::calculate_scan_session(const Genesys_Device* dev, session.params.scan_method = settings.scan_method; session.params.scan_mode = settings.scan_mode; session.params.color_filter = settings.color_filter; - session.params.flags = 0; + session.params.flags = ScanFlag::NONE; compute_session(dev, session, sensor); @@ -1032,12 +1016,6 @@ void CommandSetGl124::set_powersaving(Genesys_Device* dev, int delay /* in minut } } -static void gl124_start_action(Genesys_Device* dev) -{ - DBG_HELPER(dbg); - dev->interface->write_register(0x0f, 0x01); -} - static void gl124_stop_action(Genesys_Device* dev) { DBG_HELPER(dbg); @@ -1168,11 +1146,7 @@ void CommandSetGl124::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens val |= REG_0x01_SCAN; dev->interface->write_register(REG_0x01, val); - if (start_motor) { - dev->interface->write_register(REG_0x0F, 1); - } else { - dev->interface->write_register(REG_0x0F, 0); - } + scanner_start_action(*dev, start_motor); } @@ -1284,9 +1258,9 @@ void CommandSetGl124::slow_back_home(Genesys_Device* dev, bool wait_until_home) session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::RED; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl124_init_scan_regs(dev, sensor, &local_reg, session); @@ -1303,7 +1277,7 @@ void CommandSetGl124::slow_back_home(Genesys_Device* dev, bool wait_until_home) gl124_setup_scan_gpio(dev,resolution); try { - gl124_start_action(dev); + scanner_start_action(*dev, true); } catch (...) { catch_all_exceptions(__func__, [&]() { gl124_stop_action(dev); }); // restore original registers @@ -1377,11 +1351,11 @@ static void gl124_feed(Genesys_Device* dev, unsigned int steps, int reverse) 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_FEEDING | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::FEEDING | + ScanFlag::DISABLE_BUFFER_FULL_MOVE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl124_init_scan_regs(dev, sensor, &local_reg, session); @@ -1409,7 +1383,7 @@ static void gl124_feed(Genesys_Device* dev, unsigned int steps, int reverse) dev->interface->write_registers(local_reg); try { - gl124_start_action(dev); + scanner_start_action(*dev, true); } catch (...) { catch_all_exceptions(__func__, [&]() { gl124_stop_action (dev); }); @@ -1468,10 +1442,10 @@ void CommandSetGl124::search_start_position(Genesys_Device* dev) const session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::GREEN; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE | + ScanFlag::DISABLE_BUFFER_FULL_MOVE; compute_session(dev, session, sensor); gl124_init_scan_regs(dev, sensor, &local_reg, session); @@ -1535,11 +1509,11 @@ void CommandSetGl124::init_regs_for_coarse_calibration(Genesys_Device* dev, 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_FEEDING | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::FEEDING | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl124_init_scan_regs(dev, sensor, ®s, session); @@ -1602,10 +1576,10 @@ void CommandSetGl124::init_regs_for_shading(Genesys_Device* dev, const Genesys_S 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::DISABLE_BUFFER_FULL_MOVE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); try { @@ -1683,7 +1657,7 @@ void CommandSetGl124::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sens 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 = 0; + session.params.flags = ScanFlag::NONE; compute_session(dev, session, sensor); gl124_init_scan_regs(dev, sensor, &dev->reg, session); @@ -1824,10 +1798,10 @@ static void move_to_calibration_area(Genesys_Device* dev, const Genesys_Sensor& 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl124_init_scan_regs(dev, sensor, ®s, session); @@ -1907,10 +1881,10 @@ SensorExposure CommandSetGl124::led_calibration(Genesys_Device* dev, const Genes 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl124_init_scan_regs(dev, sensor, ®s, session); @@ -2082,10 +2056,10 @@ void CommandSetGl124::offset_calibration(Genesys_Device* dev, const Genesys_Sens 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl124_init_scan_regs(dev, sensor, ®s, session); @@ -2242,10 +2216,10 @@ void CommandSetGl124::coarse_gain_calibration(Genesys_Device* dev, const Genesys 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); try { @@ -2358,10 +2332,10 @@ void CommandSetGl124::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Se 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl124_init_scan_regs(dev, sensor, reg, session); diff --git a/backend/genesys/gl124.h b/backend/genesys/gl124.h index 93c5b5edf..e8a8caf03 100644 --- a/backend/genesys/gl124.h +++ b/backend/genesys/gl124.h @@ -109,8 +109,6 @@ static Memory_layout layouts[]={ } }; -static void gl124_start_action(Genesys_Device* dev); - static void gl124_feed(Genesys_Device* dev, unsigned int steps, int reverse); static void gl124_stop_action(Genesys_Device* dev); diff --git a/backend/genesys/gl646.cpp b/backend/genesys/gl646.cpp index 16aeca952..672b0cf6f 100644 --- a/backend/genesys/gl646.cpp +++ b/backend/genesys/gl646.cpp @@ -122,17 +122,6 @@ print_status (uint8_t val) DBG(DBG_info, "status=%s\n", msg); } -/** - * start scanner's motor - * @param dev scanner's device - */ -static void gl646_start_motor(Genesys_Device* dev) -{ - DBG_HELPER(dbg); - dev->interface->write_register(0x0f, 0x01); -} - - /** * stop scanner's motor * @param dev scanner's device @@ -353,10 +342,10 @@ static void gl646_setup_registers(Genesys_Device* dev, /* select XPA */ regs->find_reg(0x03).value &= ~REG_0x03_XPASEL; - if (session.params.flags & SCAN_FLAG_USE_XPA) { + if ((session.params.flags & ScanFlag::USE_XPA) != ScanFlag::NONE) { regs->find_reg(0x03).value |= REG_0x03_XPASEL; } - regs->state.is_xpa_on = session.params.flags & SCAN_FLAG_USE_XPA; + regs->state.is_xpa_on = (session.params.flags & ScanFlag::USE_XPA) != ScanFlag::NONE; /* R04 */ /* monochrome / color scan */ @@ -841,6 +830,9 @@ static void gl646_send_slope_table(Genesys_Device* dev, int table_nr, table[i * 2 + 1] = slope_table[i] >> 8; } + if (dev->interface->is_mock()) { + dev->interface->record_slope_table(table_nr, slope_table); + } dev->interface->write_buffer(0x3c, start_address + table_nr * 0x100, table.data(), steps * 2); } @@ -1209,8 +1201,7 @@ void CommandSetGl646::load_document(Genesys_Device* dev) const dev->interface->write_registers(regs); - gl646_start_motor(dev); - + scanner_start_action(*dev, true); count = 0; do @@ -1380,7 +1371,7 @@ void CommandSetGl646::eject_document(Genesys_Device* dev) const dev->interface->write_registers(regs); - gl646_start_motor(dev); + scanner_start_action(*dev, true); /* loop until paper sensor tells paper is out, and till motor is running */ /* use a 30 timeout */ @@ -1920,12 +1911,12 @@ static void setup_for_scan(Genesys_Device* dev, session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = settings.scan_mode; session.params.color_filter = settings.color_filter; - session.params.flags = 0; + session.params.flags = ScanFlag::NONE; if (settings.scan_method == ScanMethod::TRANSPARENCY) { - session.params.flags |= SCAN_FLAG_USE_XPA; + session.params.flags |= ScanFlag::USE_XPA; } if (xcorrection) { - session.params.flags |= SCAN_FLAG_USE_XCORRECTION; + session.params.flags |= ScanFlag::USE_XCORRECTION; } compute_session(dev, session, sensor); @@ -3519,9 +3510,9 @@ ScanSession CommandSetGl646::calculate_scan_session(const Genesys_Device* dev, session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = settings.scan_mode; session.params.color_filter = settings.color_filter; - session.params.flags = SCAN_FLAG_USE_XCORRECTION; + session.params.flags = ScanFlag::USE_XCORRECTION; if (settings.scan_method == ScanMethod::TRANSPARENCY) { - session.params.flags |= SCAN_FLAG_USE_XPA; + session.params.flags |= ScanFlag::USE_XPA; } compute_session(dev, session, sensor); diff --git a/backend/genesys/gl841.cpp b/backend/genesys/gl841.cpp index 6a68b4d6d..ad908ca35 100644 --- a/backend/genesys/gl841.cpp +++ b/backend/genesys/gl841.cpp @@ -61,6 +61,13 @@ namespace genesys { namespace gl841 { + +static int gl841_exposure_time(Genesys_Device *dev, const Genesys_Sensor& sensor, + float slope_dpi, + StepType scan_step_type, + int start, + int used_pixels); + bool CommandSetGl841::get_gain4_bit(Genesys_Register_Set* regs) const { GenesysRegister *r = sanei_genesys_get_address(regs, 0x06); @@ -573,6 +580,9 @@ static void gl841_send_slope_table(Genesys_Device* dev, int table_nr, DBG(DBG_io, "%s: %s\n", __func__, msg); } + if (dev->interface->is_mock()) { + dev->interface->record_slope_table(table_nr, slope_table); + } dev->interface->write_buffer(0x3c, start_address + table_nr * 0x200, table.data(), steps * 2); } @@ -848,12 +858,11 @@ static void gl841_init_motor_regs(Genesys_Device* dev, const Genesys_Sensor& sen gl841_write_freq(dev, dev->motor.base_ydpi / 4); fast_slope_steps = 256; - if (action == MOTOR_ACTION_FEED || action == MOTOR_ACTION_GO_HOME) - { + if (action == MOTOR_ACTION_FEED || action == MOTOR_ACTION_GO_HOME) { /* FEED and GO_HOME can use fastest slopes available */ fast_exposure = gl841_exposure_time(dev, sensor, dev->motor.base_ydpi / 4, - 0, + StepType::FULL, 0, 0); DBG(DBG_info, "%s : fast_exposure=%d pixels\n", __func__, fast_exposure); @@ -861,15 +870,14 @@ static void gl841_init_motor_regs(Genesys_Device* dev, const Genesys_Sensor& sen if (action == MOTOR_ACTION_HOME_FREE) { /* HOME_FREE must be able to stop in one step, so do not try to get faster */ - fast_exposure = dev->motor.slopes[0].maximum_start_speed; + fast_exposure = dev->motor.get_slope(StepType::FULL).legacy().maximum_start_speed; } - sanei_genesys_create_slope_table3( - dev, + sanei_genesys_create_slope_table3(dev->motor, fast_slope_table, 256, fast_slope_steps, - 0, + StepType::FULL, fast_exposure, dev->motor.base_ydpi / 4, &fast_slope_steps, @@ -975,7 +983,7 @@ static void gl841_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor Genesys_Register_Set* reg, unsigned int scan_exposure_time,/*pixel*/ unsigned scan_yres, // dpi, motor resolution - int scan_step_type,/*0: full, 1: half, 2: quarter*/ + StepType scan_step_type, unsigned int scan_lines,/*lines, scan resolution*/ unsigned int scan_dummy, // number of scan lines to add in a scan_lines line @@ -985,8 +993,8 @@ static void gl841_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor { DBG_HELPER_ARGS(dbg, "scan_exposure_time=%d, scan_yres=%d, scan_step_type=%d, scan_lines=%d," " scan_dummy=%d, feed_steps=%d, flags=%x", - scan_exposure_time, scan_yres, scan_step_type, scan_lines, scan_dummy, - feed_steps, flags); + scan_exposure_time, scan_yres, static_cast(scan_step_type), + scan_lines, scan_dummy, feed_steps, flags); unsigned int fast_exposure; int use_fast_fed = 0; unsigned int fast_time; @@ -1006,7 +1014,7 @@ static void gl841_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor fast_exposure = gl841_exposure_time(dev, sensor, dev->motor.base_ydpi / 4, - 0, + StepType::FULL, 0, 0); @@ -1028,8 +1036,7 @@ static void gl841_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor how many steps we need for slow acceleration and how much steps we are allowed to use. */ - slow_slope_time = sanei_genesys_create_slope_table3 ( - dev, + slow_slope_time = sanei_genesys_create_slope_table3(dev->motor, slow_slope_table, 256, 256, scan_step_type, @@ -1038,8 +1045,7 @@ static void gl841_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor &slow_slope_steps, nullptr); - sanei_genesys_create_slope_table3 ( - dev, + sanei_genesys_create_slope_table3(dev->motor, back_slope_table, 256, 256, scan_step_type, @@ -1048,27 +1054,28 @@ static void gl841_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor &back_slope_steps, nullptr); - if (feed_steps < (slow_slope_steps >> scan_step_type)) { + if (feed_steps < (slow_slope_steps >> static_cast(scan_step_type))) { /*TODO: what should we do here?? go back to exposure calculation?*/ - feed_steps = slow_slope_steps >> scan_step_type; + feed_steps = slow_slope_steps >> static_cast(scan_step_type); } if (feed_steps > fast_slope_steps*2 - - (slow_slope_steps >> scan_step_type)) - fast_slope_steps = 256; - else -/* we need to shorten fast_slope_steps here. */ - fast_slope_steps = (feed_steps - - (slow_slope_steps >> scan_step_type))/2; + (slow_slope_steps >> static_cast(scan_step_type))) + { + fast_slope_steps = 256; + } else { + // we need to shorten fast_slope_steps here. + fast_slope_steps = (feed_steps - + (slow_slope_steps >> static_cast(scan_step_type))) / 2; + } DBG(DBG_info, "%s: Maximum allowed slope steps for fast slope: %d\n", __func__, fast_slope_steps); - fast_slope_time = sanei_genesys_create_slope_table3 ( - dev, + fast_slope_time = sanei_genesys_create_slope_table3(dev->motor, fast_slope_table, 256, fast_slope_steps, - 0, + StepType::FULL, fast_exposure, dev->motor.base_ydpi / 4, &fast_slope_steps, @@ -1082,9 +1089,11 @@ static void gl841_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor 2-feed mode */ use_fast_fed = 0; } - else if (feed_steps < fast_slope_steps*2 + (slow_slope_steps >> scan_step_type)) { - use_fast_fed = 0; - DBG(DBG_info, "%s: feed too short, slow move forced.\n", __func__); + else if (feed_steps < fast_slope_steps * 2 + + (slow_slope_steps >> static_cast(scan_step_type))) + { + use_fast_fed = 0; + DBG(DBG_info, "%s: feed too short, slow move forced.\n", __func__); } else { /* for deciding whether we should use fast mode we need to check how long we need for (fast)accelerating, moving, decelerating, (TODO: stopping?) @@ -1097,11 +1106,11 @@ static void gl841_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor fast_time = fast_exposure / 4 * (feed_steps - fast_slope_steps*2 - - (slow_slope_steps >> scan_step_type)) + (slow_slope_steps >> static_cast(scan_step_type))) + fast_slope_time*2 + slow_slope_time; slow_time = (scan_exposure_time * scan_yres) / dev->motor.base_ydpi * - (feed_steps - (slow_slope_steps >> scan_step_type)) + (feed_steps - (slow_slope_steps >> static_cast(scan_step_type))) + slow_slope_time; DBG(DBG_info, "%s: Time for slow move: %d\n", __func__, slow_time); @@ -1110,14 +1119,14 @@ static void gl841_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor use_fast_fed = fast_time < slow_time; } - if (use_fast_fed) - feedl = feed_steps - fast_slope_steps*2 - - (slow_slope_steps >> scan_step_type); - else - if ((feed_steps << scan_step_type) < slow_slope_steps) - feedl = 0; - else - feedl = (feed_steps << scan_step_type) - slow_slope_steps; + if (use_fast_fed) { + feedl = feed_steps - fast_slope_steps * 2 - + (slow_slope_steps >> static_cast(scan_step_type)); + } else if ((feed_steps << static_cast(scan_step_type)) < slow_slope_steps) { + feedl = 0; + } else { + feedl = (feed_steps << static_cast(scan_step_type)) - slow_slope_steps; + } DBG(DBG_info, "%s: Decided to use %s mode\n", __func__, use_fast_fed?"fast feed":"slow feed"); /* all needed slopes available. we did even decide which mode to use. @@ -1257,7 +1266,7 @@ HOME_FREE: 3 r->value |= scan_dummy; r = sanei_genesys_get_address (reg, 0x67); - r->value = 0x3f | (scan_step_type << 6); + r->value = 0x3f | (static_cast(scan_step_type) << 6); r = sanei_genesys_get_address (reg, 0x68); r->value = 0x3f; @@ -1337,7 +1346,7 @@ static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens /* enable shading */ r = sanei_genesys_get_address (reg, 0x01); r->value |= REG_0x01_SCAN; - if ((session.params.flags & SCAN_FLAG_DISABLE_SHADING) || + if (has_flag(session.params.flags, ScanFlag::DISABLE_SHADING) || (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) { r->value &= ~REG_0x01_DVDSET; } else { @@ -1350,7 +1359,7 @@ static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens r = sanei_genesys_get_address (reg, 0x03); r->value |= REG_0x03_AVEENB; sanei_genesys_set_lamp_power(dev, sensor, *reg, - !(session.params.flags & SCAN_FLAG_DISABLE_LAMP)); + !has_flag(session.params.flags, ScanFlag::DISABLE_LAMP)); /* BW threshold */ r = sanei_genesys_get_address (reg, 0x2e); @@ -1374,7 +1383,7 @@ static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens /* AFEMOD should depend on FESET, and we should set these * bits separately */ r->value &= ~(REG_0x04_FILTER | REG_0x04_AFEMOD); - if (session.params.flags & SCAN_FLAG_ENABLE_LEDADD) { + if (has_flag(session.params.flags, ScanFlag::ENABLE_LEDADD)) { r->value |= 0x10; /* no filter */ } else if (session.params.channels == 1) @@ -1409,7 +1418,7 @@ static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens /* CIS scanners can do true gray by setting LEDADD */ r = sanei_genesys_get_address (reg, 0x87); r->value &= ~REG_0x87_LEDADD; - if (session.params.flags & SCAN_FLAG_ENABLE_LEDADD) { + if (has_flag(session.params.flags, ScanFlag::ENABLE_LEDADD)) { r->value |= REG_0x87_LEDADD; expr = reg->get16(REG_EXPR); expg = reg->get16(REG_EXPG); @@ -1479,7 +1488,7 @@ gl841_get_led_exposure(Genesys_Device * dev, const Genesys_Sensor& sensor) static int gl841_exposure_time(Genesys_Device *dev, const Genesys_Sensor& sensor, float slope_dpi, - int scan_step_type, + StepType scan_step_type, int start, int used_pixels) { @@ -1503,33 +1512,29 @@ int led_exposure; * @param dev device * @param yres motor resolution */ -static int -gl841_scan_step_type(Genesys_Device *dev, int yres) +static StepType gl841_scan_step_type(Genesys_Device *dev, int yres) { -int scan_step_type=0; + StepType type = StepType::FULL; /* TODO : check if there is a bug around the use of max_step_type */ /* should be <=1, need to chek all devices entry in genesys_devices */ - if (yres*4 < dev->motor.base_ydpi || dev->motor.max_step_type <= 0) + if (yres * 4 < dev->motor.base_ydpi || dev->motor.max_step_type() == StepType::FULL) { + type = StepType::FULL; + } else if (yres * 4 < dev->motor.base_ydpi * 2 || + dev->motor.max_step_type() <= StepType::HALF) { - scan_step_type = 0; - } - else if (yres*4 < dev->motor.base_ydpi*2 || dev->motor.max_step_type <= 1) - { - scan_step_type = 1; - } - else - { - scan_step_type = 2; + type = StepType::HALF; + } else { + type = StepType::QUARTER; } /* this motor behaves differently */ if (dev->model->motor_id==MotorId::CANON_LIDE_80) { - /* driven by 'frequency' tables ? */ - scan_step_type = 0; + // driven by 'frequency' tables ? + type = StepType::FULL; } - return scan_step_type; + return type; } // set up registers for an actual scan this function sets up the scanner to scan in normal or single @@ -1545,7 +1550,6 @@ static void gl841_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens int slope_dpi = 0; int dummy = 0; - int scan_step_type = 1; /* results: @@ -1613,7 +1617,7 @@ dummy \ scanned lines slope_dpi = slope_dpi * (1 + dummy); - scan_step_type = gl841_scan_step_type(dev, session.params.yres); + StepType scan_step_type = gl841_scan_step_type(dev, session.params.yres); exposure_time = gl841_exposure_time(dev, sensor, slope_dpi, scan_step_type, @@ -1638,7 +1642,7 @@ dummy \ scanned lines /* move = ((move + dummy) / (dummy + 1)) * (dummy + 1); DBG(DBG_info, "%s: move=%d steps\n", __func__, move);*/ - if (session.params.flags & SCAN_FLAG_SINGLE_LINE) { + if (has_flag(session.params.flags, ScanFlag::SINGLE_LINE)) { gl841_init_motor_regs_off(reg, dev->model->is_cis ? session.output_line_count * session.params.channels : session.output_line_count); } else { @@ -1646,7 +1650,7 @@ dummy \ scanned lines dev->model->is_cis ? session.output_line_count * session.params.channels : session.output_line_count, dummy, move, - (session.params.flags & SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE) ? + has_flag(session.params.flags, ScanFlag::DISABLE_BUFFER_FULL_MOVE) ? MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE : 0); } @@ -1693,7 +1697,7 @@ ScanSession CommandSetGl841::calculate_scan_session(const Genesys_Device* dev, session.params.scan_method = settings.scan_method; session.params.scan_mode = settings.scan_mode; session.params.color_filter = settings.color_filter; - session.params.flags = 0; + session.params.flags = ScanFlag::NONE; compute_session(dev, session, sensor); @@ -1861,12 +1865,6 @@ void CommandSetGl841::set_powersaving(Genesys_Device* dev, int delay /* in minut dev->interface->write_registers(local_reg); } -static void gl841_start_action(Genesys_Device* dev) -{ - DBG_HELPER(dbg); - dev->interface->write_register(0x0f, 0x01); -} - static void gl841_stop_action(Genesys_Device* dev) { DBG_HELPER(dbg); @@ -1963,7 +1961,7 @@ void CommandSetGl841::eject_document(Genesys_Device* dev) const dev->interface->write_registers(local_reg); try { - gl841_start_action(dev); + scanner_start_action(*dev, true); } catch (...) { catch_all_exceptions(__func__, [&]() { gl841_stop_action(dev); }); // restore original registers @@ -2157,6 +2155,7 @@ void CommandSetGl841::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens local_reg.init_reg(0x01, reg->get8(0x01) | REG_0x01_SCAN); local_reg.init_reg(0x0d, 0x01); + // scanner_start_action(dev, start_motor) if (start_motor) { local_reg.init_reg(0x0f, 0x01); } else { @@ -2201,7 +2200,7 @@ static void gl841_feed(Genesys_Device* dev, int steps) dev->interface->write_registers(local_reg); try { - gl841_start_action(dev); + scanner_start_action(*dev, true); } catch (...) { catch_all_exceptions(__func__, [&]() { gl841_stop_action (dev); }); // restore original registers @@ -2317,7 +2316,7 @@ void CommandSetGl841::slow_back_home(Genesys_Device* dev, bool wait_until_home) dev->interface->write_registers(local_reg); try { - gl841_start_action(dev); + scanner_start_action(*dev, true); } catch (...) { catch_all_exceptions(__func__, [&]() { gl841_stop_action(dev); }); // restore original registers @@ -2390,10 +2389,10 @@ void CommandSetGl841::search_start_position(Genesys_Device* dev) const session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::GREEN; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE | + ScanFlag::DISABLE_BUFFER_FULL_MOVE; compute_session(dev, session, sensor); gl841_init_scan_regs(dev, sensor, &local_reg, session); @@ -2457,10 +2456,10 @@ void CommandSetGl841::init_regs_for_coarse_calibration(Genesys_Device* dev, 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl841_init_scan_regs(dev, sensor, ®s, session); @@ -2529,10 +2528,10 @@ void CommandSetGl841::init_regs_for_shading(Genesys_Device* dev, const Genesys_S 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - /*SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE |*/ - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + /*ScanFlag::DISABLE_BUFFER_FULL_MOVE |*/ + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, calib_sensor); gl841_init_scan_regs(dev, calib_sensor, ®s, session); @@ -2546,7 +2545,6 @@ void CommandSetGl841::init_regs_for_shading(Genesys_Device* dev, const Genesys_S void CommandSetGl841::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const { DBG_HELPER(dbg); - int flags; float move; int move_dpi; float start; @@ -2599,7 +2597,7 @@ void CommandSetGl841::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sens /* we enable true gray for cis scanners only, and just when doing * scan since color calibration is OK for this mode */ - flags = 0; + ScanFlag flags = ScanFlag::NONE; /* true gray (led add for cis scanners) */ if(dev->model->is_cis && dev->settings.true_gray @@ -2608,7 +2606,7 @@ void CommandSetGl841::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sens { // on Lide 80 the LEDADD bit results in only red LED array being lit DBG(DBG_io, "%s: activating LEDADD\n", __func__); - flags |= SCAN_FLAG_ENABLE_LEDADD; + flags |= ScanFlag::ENABLE_LEDADD; } ScanSession session; @@ -2702,10 +2700,10 @@ SensorExposure CommandSetGl841::led_calibration(Genesys_Device* dev, const Genes 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, calib_sensor_base); gl841_init_scan_regs(dev, calib_sensor_base, ®s, session); @@ -2913,10 +2911,10 @@ static void ad_fe_offset_calibration(Genesys_Device* dev, const Genesys_Sensor& 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, calib_sensor); gl841_init_scan_regs(dev, calib_sensor, ®s, session); @@ -3042,11 +3040,11 @@ void CommandSetGl841::offset_calibration(Genesys_Device* dev, const Genesys_Sens 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE | - SCAN_FLAG_DISABLE_LAMP; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE | + ScanFlag::DISABLE_LAMP; compute_session(dev, session, calib_sensor); gl841_init_scan_regs(dev, calib_sensor, ®s, session); @@ -3413,10 +3411,10 @@ void CommandSetGl841::coarse_gain_calibration(Genesys_Device* dev, const Genesys 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, calib_sensor); gl841_init_scan_regs(dev, calib_sensor, ®s, session); @@ -3566,10 +3564,10 @@ void CommandSetGl841::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Se session.params.scan_mode = ScanColorMode::GRAY; } session.params.color_filter = dev->settings.color_filter; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl841_init_scan_regs(dev, sensor, local_reg, session); @@ -3685,10 +3683,10 @@ void CommandSetGl841::init(Genesys_Device* dev) const 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, calib_sensor); gl841_init_scan_regs(dev, calib_sensor, ®s, session); @@ -3815,7 +3813,7 @@ void CommandSetGl841::search_strip(Genesys_Device* dev, const Genesys_Sensor& se session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::RED; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | SCAN_FLAG_DISABLE_GAMMA; + session.params.flags = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA; compute_session(dev, session, sensor); size = pixels * channels * lines * (session.params.depth / 8); diff --git a/backend/genesys/gl841.h b/backend/genesys/gl841.h index ac29ca1ad..2b91c05fd 100644 --- a/backend/genesys/gl841.h +++ b/backend/genesys/gl841.h @@ -50,17 +50,6 @@ namespace genesys { namespace gl841 { -/** - * prototypes declaration in case of unit testing - */ - -static -int gl841_exposure_time(Genesys_Device *dev, const Genesys_Sensor& sensor, - float slope_dpi, - int scan_step_type, - int start, - int used_pixels); - class CommandSetGl841 : public CommandSet { public: diff --git a/backend/genesys/gl843.cpp b/backend/genesys/gl843.cpp index 8f8786544..45cc5172a 100644 --- a/backend/genesys/gl843.cpp +++ b/backend/genesys/gl843.cpp @@ -717,6 +717,10 @@ static void gl843_send_slope_table(Genesys_Device* dev, int table_nr, 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 : 0x40000, 0x48000, 0x50000, 0x58000, 0x60000 // XXX STEF XXX USB 1.1 ? sanei_genesys_write_0x8c (dev, 0x0f, 0x14); dev->interface->write_gamma(0x28, 0x40000 + 0x8000 * table_nr, table.data(), steps * 2, @@ -813,9 +817,9 @@ void CommandSetGl843::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, static void gl843_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, Genesys_Register_Set* reg, + const Motor_Profile& motor_profile, unsigned int exposure, unsigned scan_yres, - StepType step_type, unsigned int scan_lines, unsigned int scan_dummy, unsigned int feed_steps, @@ -823,14 +827,11 @@ static void gl843_init_motor_regs_scan(Genesys_Device* dev, { DBG_HELPER_ARGS(dbg, "exposure=%d, scan_yres=%d, step_type=%d, scan_lines=%d, scan_dummy=%d, " "feed_steps=%d, flags=%x", - exposure, scan_yres, static_cast(step_type), scan_lines, scan_dummy, + exposure, scan_yres, static_cast(motor_profile.step_type), scan_lines, scan_dummy, feed_steps, flags); int use_fast_fed, coeff; unsigned int lincnt; - std::vector scan_table; - std::vector fast_table; - int scan_steps,fast_steps; unsigned int feedl,factor,dist; GenesysRegister *r; uint32_t z1, z2; @@ -872,65 +873,56 @@ static void gl843_init_motor_regs_scan(Genesys_Device* dev, } /* scan and backtracking slope table */ - sanei_genesys_slope_table(scan_table, - &scan_steps, - scan_yres, - exposure, - dev->motor.base_ydpi, - step_type, - factor, - dev->model->motor_id, - gl843_motor_profiles); - gl843_send_slope_table(dev, SCAN_TABLE, scan_table, scan_steps * factor); - gl843_send_slope_table(dev, BACKTRACK_TABLE, scan_table, scan_steps * factor); + auto scan_table = sanei_genesys_slope_table(scan_yres, exposure, dev->motor.base_ydpi, + factor, motor_profile); + + gl843_send_slope_table(dev, SCAN_TABLE, scan_table.table, scan_table.scan_steps * factor); + gl843_send_slope_table(dev, BACKTRACK_TABLE, scan_table.table, scan_table.scan_steps * factor); /* STEPNO */ r = sanei_genesys_get_address(reg, REG_STEPNO); - r->value = scan_steps; + r->value = scan_table.scan_steps; /* FSHDEC */ r = sanei_genesys_get_address(reg, REG_FSHDEC); - r->value = scan_steps; + r->value = scan_table.scan_steps; /* fast table */ + // BUG: looks like for fast moves we use inconsistent step type StepType fast_step_type = StepType::FULL; - if (static_cast(step_type) <= static_cast(fast_step_type)) { - fast_step_type = step_type; + if (static_cast(motor_profile.step_type) <= static_cast(fast_step_type)) { + fast_step_type = motor_profile.step_type; } + Motor_Profile fast_motor_profile = motor_profile; + fast_motor_profile.step_type = fast_step_type; + unsigned fast_yres = sanei_genesys_get_lowest_ydpi(dev); if (dev->model->model_id == ModelId::CANON_4400F) { fast_yres = scan_yres; } - sanei_genesys_slope_table(fast_table, - &fast_steps, - fast_yres, - exposure, - dev->motor.base_ydpi, - fast_step_type, - factor, - dev->model->motor_id, - gl843_motor_profiles); - gl843_send_slope_table(dev, STOP_TABLE, fast_table, fast_steps * factor); - gl843_send_slope_table(dev, FAST_TABLE, fast_table, fast_steps * factor); - gl843_send_slope_table(dev, HOME_TABLE, fast_table, fast_steps * factor); + auto fast_table = sanei_genesys_slope_table(fast_yres, exposure, dev->motor.base_ydpi, + factor, fast_motor_profile); + gl843_send_slope_table(dev, STOP_TABLE, fast_table.table, fast_table.scan_steps * factor); + gl843_send_slope_table(dev, FAST_TABLE, fast_table.table, fast_table.scan_steps * factor); + gl843_send_slope_table(dev, HOME_TABLE, fast_table.table, fast_table.scan_steps * factor); /* FASTNO */ r = sanei_genesys_get_address(reg, REG_FASTNO); - r->value = fast_steps; + r->value = fast_table.scan_steps; /* FMOVNO */ r = sanei_genesys_get_address(reg, REG_FMOVNO); - r->value = fast_steps; + r->value = fast_table.scan_steps; /* substract acceleration distance from feedl */ feedl=feed_steps; - feedl <<= static_cast(step_type); + feedl <<= static_cast(motor_profile.step_type); - dist = scan_steps; + dist = scan_table.scan_steps; if (use_fast_fed) { - dist += fast_steps*2; + dist += fast_table.scan_steps*2; } DBG(DBG_io2, "%s: acceleration distance=%d\n", __func__, dist); @@ -946,12 +938,12 @@ static void gl843_init_motor_regs_scan(Genesys_Device* dev, DBG(DBG_io, "%s: feedl=%d\n", __func__, feedl); /* doesn't seem to matter that much */ - sanei_genesys_calculate_zmod (use_fast_fed, + sanei_genesys_calculate_zmod(use_fast_fed, exposure, - scan_table, - scan_steps, + scan_table.table, + scan_table.scan_steps, feedl, - scan_steps, + scan_table.scan_steps, &z1, &z2); if(scan_yres>600) @@ -970,12 +962,12 @@ static void gl843_init_motor_regs_scan(Genesys_Device* dev, r->value &= 0xf0; /* 0 dummy lines */ r->value |= scan_dummy; /* dummy lines */ - reg->set8_mask(REG_0x67, static_cast(step_type) << REG_0x67S_STEPSEL, 0xc0); - reg->set8_mask(REG_0x68, static_cast(step_type) << REG_0x68S_FSTPSEL, 0xc0); + reg->set8_mask(REG_0x67, static_cast(motor_profile.step_type) << REG_0x67S_STEPSEL, 0xc0); + reg->set8_mask(REG_0x68, static_cast(motor_profile.step_type) << REG_0x68S_FSTPSEL, 0xc0); /* steps for STOP table */ r = sanei_genesys_get_address(reg, REG_FMOVDEC); - r->value = fast_steps; + r->value = fast_table.scan_steps; /* Vref XXX STEF XXX : optical divider or step type ? */ r = sanei_genesys_get_address (reg, 0x80); @@ -1053,7 +1045,7 @@ static void gl843_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens /* enable shading */ r = sanei_genesys_get_address (reg, REG_0x01); r->value &= ~REG_0x01_SCAN; - if ((session.params.flags & SCAN_FLAG_DISABLE_SHADING) || + if (has_flag(session.params.flags, ScanFlag::DISABLE_SHADING) || (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION || (dev->model->flags & GENESYS_FLAG_CALIBRATION_HOST_SIDE))) { @@ -1082,14 +1074,14 @@ static void gl843_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens // FIXME: we probably don't need to set exposure to registers at this point. It was this way // before a refactor. sanei_genesys_set_lamp_power(dev, sensor, *reg, - !(session.params.flags & SCAN_FLAG_DISABLE_LAMP)); + !has_flag(session.params.flags, ScanFlag::DISABLE_LAMP)); /* select XPA */ r->value &= ~REG_0x03_XPASEL; - if (session.params.flags & SCAN_FLAG_USE_XPA) { + if (has_flag(session.params.flags, ScanFlag::USE_XPA)) { r->value |= REG_0x03_XPASEL; } - reg->state.is_xpa_on = session.params.flags & SCAN_FLAG_USE_XPA; + reg->state.is_xpa_on = has_flag(session.params.flags, ScanFlag::USE_XPA); /* BW threshold */ r = sanei_genesys_get_address(reg, REG_0x2E); @@ -1206,32 +1198,33 @@ static void gl843_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens if (exposure < 0) { throw std::runtime_error("Exposure not defined in sensor definition"); } - StepType scan_step_type = sanei_genesys_compute_step_type(gl843_motor_profiles, - dev->model->motor_id, - exposure); + const auto& motor_profile = sanei_genesys_get_motor_profile(*gl843_motor_profiles, + dev->model->motor_id, + exposure); DBG(DBG_info, "%s : exposure=%d pixels\n", __func__, exposure); - DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, static_cast(scan_step_type)); + DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, + static_cast(motor_profile.step_type)); // now _LOGICAL_ optical values used are known, setup registers gl843_init_optical_regs_scan(dev, sensor, reg, exposure, session); /*** motor parameters ***/ mflags = 0; - if (session.params.flags & SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE) { + if (has_flag(session.params.flags, ScanFlag::DISABLE_BUFFER_FULL_MOVE)) { mflags |= MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE; } - if (session.params.flags & SCAN_FLAG_FEEDING) { + if (has_flag(session.params.flags, ScanFlag::FEEDING)) { mflags |= MOTOR_FLAG_FEED; } - if (session.params.flags & SCAN_FLAG_USE_XPA) { + if (has_flag(session.params.flags, ScanFlag::USE_XPA)) { mflags |= MOTOR_FLAG_USE_XPA; } unsigned scan_lines = dev->model->is_cis ? session.output_line_count * session.params.channels : session.output_line_count; - gl843_init_motor_regs_scan(dev, sensor, reg, exposure, slope_dpi, scan_step_type, + gl843_init_motor_regs_scan(dev, sensor, reg, motor_profile, exposure, slope_dpi, scan_lines, dummy, session.params.starty, mflags); dev->read_buffer.clear(); @@ -1291,7 +1284,7 @@ ScanSession CommandSetGl843::calculate_scan_session(const Genesys_Device* dev, session.params.scan_method = settings.scan_method; session.params.scan_mode = settings.scan_mode; session.params.color_filter = settings.color_filter; - session.params.flags = 0; + session.params.flags = ScanFlag::NONE; compute_session(dev, session, sensor); @@ -1325,12 +1318,6 @@ void CommandSetGl843::set_powersaving(Genesys_Device* dev, int delay /* in minut DBG_HELPER_ARGS(dbg, "delay = %d", delay); } -static void gl843_start_action(Genesys_Device* dev) -{ - DBG_HELPER(dbg); - dev->interface->write_register(0x0f, 0x01); -} - static void gl843_stop_action_no_move(Genesys_Device* dev, Genesys_Register_Set* reg) { DBG_HELPER(dbg); @@ -1726,11 +1713,7 @@ void CommandSetGl843::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens val |= REG_0x01_SCAN; dev->interface->write_register(REG_0x01, val); - if (start_motor) { - dev->interface->write_register(REG_0x0F, 1); - } else { - dev->interface->write_register(REG_0x0F, 0); - } + scanner_start_action(*dev, start_motor); } @@ -1784,7 +1767,7 @@ static void gl843_park_xpa_lamp(Genesys_Device* dev) dev->interface->write_registers(local_reg); gl843_set_xpa_motor_power(dev, true); try { - gl843_start_action(dev); + scanner_start_action(*dev, true); } catch (...) { catch_all_exceptions(__func__, [&]() { gl843_stop_action(dev); }); // restore original registers @@ -1873,10 +1856,10 @@ void CommandSetGl843::slow_back_home(Genesys_Device* dev, bool wait_until_home) session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::LINEART; session.params.color_filter = dev->settings.color_filter; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::DISABLE_BUFFER_FULL_MOVE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl843_init_scan_regs(dev, sensor, &local_reg, session); @@ -1893,7 +1876,7 @@ void CommandSetGl843::slow_back_home(Genesys_Device* dev, bool wait_until_home) dev->interface->write_registers(local_reg); try { - gl843_start_action(dev); + scanner_start_action(*dev, true); } catch (...) { catch_all_exceptions(__func__, [&]() { gl843_stop_action(dev); }); // restore original registers @@ -1971,10 +1954,10 @@ void CommandSetGl843::search_start_position(Genesys_Device* dev) const session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::GREEN; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE | + ScanFlag::DISABLE_BUFFER_FULL_MOVE; compute_session(dev, session, sensor); gl843_init_scan_regs(dev, sensor, &local_reg, session); @@ -2023,14 +2006,14 @@ void CommandSetGl843::init_regs_for_coarse_calibration(Genesys_Device* dev, { DBG_HELPER(dbg); - int flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + ScanFlag flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) { - flags |= SCAN_FLAG_USE_XPA; + flags |= ScanFlag::USE_XPA; } ScanSession session; @@ -2089,10 +2072,10 @@ static void gl843_feed(Genesys_Device* dev, unsigned int steps) 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_FEEDING | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::FEEDING | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl843_init_scan_regs(dev, sensor, &local_reg, session); @@ -2109,7 +2092,7 @@ static void gl843_feed(Genesys_Device* dev, unsigned int steps) dev->interface->write_registers(local_reg); try { - gl843_start_action(dev); + scanner_start_action(*dev, true); } catch (...) { catch_all_exceptions(__func__, [&]() { gl843_stop_action(dev); }); // restore original registers @@ -2186,10 +2169,10 @@ void CommandSetGl843::init_regs_for_shading(Genesys_Device* dev, const Genesys_S dev->calib_resolution = resolution; - int flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + ScanFlag flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::DISABLE_BUFFER_FULL_MOVE | + ScanFlag::IGNORE_LINE_DISTANCE; if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) @@ -2197,7 +2180,7 @@ void CommandSetGl843::init_regs_for_shading(Genesys_Device* dev, const Genesys_S // note: move_to_ta() function has already been called and the sensor is at the // transparency adapter move = static_cast(dev->model->y_offset_calib_white_ta - dev->model->y_offset_sensor_to_ta); - flags |= SCAN_FLAG_USE_XPA; + flags |= ScanFlag::USE_XPA; } else { move = static_cast(dev->model->y_offset_calib_white); } @@ -2237,7 +2220,6 @@ void CommandSetGl843::init_regs_for_shading(Genesys_Device* dev, const Genesys_S void CommandSetGl843::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const { DBG_HELPER(dbg); - int flags; float move; int move_dpi; float start; @@ -2246,7 +2228,7 @@ void CommandSetGl843::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sens move_dpi = dev->motor.base_ydpi; - flags = 0; + ScanFlag flags = ScanFlag::NONE; if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) @@ -2258,7 +2240,7 @@ void CommandSetGl843::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sens } else { move = static_cast(dev->model->y_offset_ta - dev->model->y_offset_sensor_to_ta); } - flags |= SCAN_FLAG_USE_XPA; + flags |= ScanFlag::USE_XPA; } else { if (dev->ignore_offsets) { move = 0; @@ -2379,10 +2361,10 @@ SensorExposure CommandSetGl843::led_calibration(Genesys_Device* dev, const Genes 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, calib_sensor); gl843_init_scan_regs(dev, calib_sensor, ®s, session); @@ -2579,15 +2561,15 @@ void CommandSetGl843::offset_calibration(Genesys_Device* dev, const Genesys_Sens target_pixels = static_cast((target_pixels * calib_sensor.optical_res) / MM_PER_INCH); } - int flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + ScanFlag flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) { - flags |= SCAN_FLAG_USE_XPA; + flags |= ScanFlag::USE_XPA; } ScanSession session; @@ -2799,15 +2781,15 @@ void CommandSetGl843::coarse_gain_calibration(Genesys_Device* dev, const Genesys lines=10; int target_pixels = sensor.sensor_pixels / factor; - int flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + ScanFlag flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) { - flags |= SCAN_FLAG_USE_XPA; + flags |= ScanFlag::USE_XPA; } const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, channels, @@ -2941,10 +2923,10 @@ void CommandSetGl843::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Se 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, calib_sensor); gl843_init_scan_regs(dev, calib_sensor, reg, session); @@ -3188,7 +3170,7 @@ void CommandSetGl843::search_strip(Genesys_Device* dev, const Genesys_Sensor& se session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::RED; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | SCAN_FLAG_DISABLE_SHADING; + session.params.flags = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_SHADING; compute_session(dev, session, calib_sensor); gl843_init_scan_regs(dev, calib_sensor, &local_reg, session); diff --git a/backend/genesys/gl846.cpp b/backend/genesys/gl846.cpp index 16401c322..c0ef21043 100644 --- a/backend/genesys/gl846.cpp +++ b/backend/genesys/gl846.cpp @@ -296,6 +296,9 @@ static void gl846_send_slope_table(Genesys_Device* dev, int table_nr, 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()); } @@ -368,9 +371,9 @@ void CommandSetGl846::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, static void gl846_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, Genesys_Register_Set* reg, + const Motor_Profile& motor_profile, unsigned int scan_exposure_time, unsigned scan_yres, - StepType step_type, unsigned int scan_lines, unsigned int scan_dummy, unsigned int feed_steps, @@ -378,13 +381,11 @@ static void gl846_init_motor_regs_scan(Genesys_Device* dev, { DBG_HELPER_ARGS(dbg, "scan_exposure_time=%d, scan_yres=%d, step_type=%d, scan_lines=%d, " "scan_dummy=%d, feed_steps=%d, flags=%x", - scan_exposure_time, scan_yres, static_cast(step_type), scan_lines, - scan_dummy, feed_steps, flags); + scan_exposure_time, scan_yres, static_cast(motor_profile.step_type), + scan_lines, scan_dummy, feed_steps, flags); int use_fast_fed; unsigned int fast_dpi; - std::vector scan_table; - std::vector fast_table; - int scan_steps, fast_steps, factor; + int factor; unsigned int feedl, dist; GenesysRegister *r; uint32_t z1, z2; @@ -427,49 +428,39 @@ static void gl846_init_motor_regs_scan(Genesys_Device* dev, } /* scan and backtracking slope table */ - sanei_genesys_slope_table(scan_table, - &scan_steps, - scan_yres, - scan_exposure_time, - dev->motor.base_ydpi, - step_type, - factor, - dev->model->motor_id, - gl846_motor_profiles); - gl846_send_slope_table(dev, SCAN_TABLE, scan_table, scan_steps * factor); - gl846_send_slope_table(dev, BACKTRACK_TABLE, scan_table, scan_steps * factor); + auto scan_table = sanei_genesys_slope_table(scan_yres, scan_exposure_time, dev->motor.base_ydpi, + factor, motor_profile); + gl846_send_slope_table(dev, SCAN_TABLE, scan_table.table, scan_table.scan_steps * factor); + gl846_send_slope_table(dev, BACKTRACK_TABLE, scan_table.table, scan_table.scan_steps * factor); /* fast table */ fast_dpi=sanei_genesys_get_lowest_ydpi(dev); - StepType fast_step_type = step_type; - if (static_cast(step_type) >= static_cast(StepType::QUARTER)) { + // BUG: looks like for fast moves we use inconsistent step type + StepType fast_step_type = motor_profile.step_type; + if (static_cast(motor_profile.step_type) >= static_cast(StepType::QUARTER)) { fast_step_type = StepType::QUARTER; } - sanei_genesys_slope_table(fast_table, - &fast_steps, - fast_dpi, - scan_exposure_time, - dev->motor.base_ydpi, - fast_step_type, - factor, - dev->model->motor_id, - gl846_motor_profiles); + Motor_Profile fast_motor_profile = motor_profile; + fast_motor_profile.step_type = fast_step_type; - /* manual override of high start value */ - fast_table[0]=fast_table[1]; + auto fast_table = sanei_genesys_slope_table(fast_dpi, scan_exposure_time, dev->motor.base_ydpi, + factor, fast_motor_profile); - gl846_send_slope_table(dev, STOP_TABLE, fast_table, fast_steps * factor); - gl846_send_slope_table(dev, FAST_TABLE, fast_table, fast_steps * factor); - gl846_send_slope_table(dev, HOME_TABLE, fast_table, fast_steps * factor); + // manual override of high start value + fast_table.table[0] = fast_table.table[1]; + + gl846_send_slope_table(dev, STOP_TABLE, fast_table.table, fast_table.scan_steps * factor); + gl846_send_slope_table(dev, FAST_TABLE, fast_table.table, fast_table.scan_steps * factor); + gl846_send_slope_table(dev, HOME_TABLE, fast_table.table, fast_table.scan_steps * factor); /* correct move distance by acceleration and deceleration amounts */ feedl=feed_steps; if (use_fast_fed) { feedl <<= static_cast(fast_step_type); - dist=(scan_steps+2*fast_steps)*factor; + dist = (scan_table.scan_steps + 2 * fast_table.scan_steps) * factor; /* TODO read and decode REG_0xAB */ r = sanei_genesys_get_address (reg, 0x5e); dist += (r->value & 31); @@ -479,12 +470,12 @@ static void gl846_init_motor_regs_scan(Genesys_Device* dev, } else { - feedl <<= static_cast(step_type); - dist=scan_steps*factor; + feedl <<= static_cast(motor_profile.step_type); + dist=scan_table.scan_steps*factor; if (flags & MOTOR_FLAG_FEED) dist *=2; } - DBG (DBG_io2, "%s: scan steps=%d\n", __func__, scan_steps); + DBG (DBG_io2, "%s: scan steps=%d\n", __func__, scan_table.scan_steps); DBG (DBG_io2, "%s: acceleration distance=%d\n", __func__, dist); /* check for overflow */ @@ -510,9 +501,9 @@ static void gl846_init_motor_regs_scan(Genesys_Device* dev, /* if quarter step, bipolar Vref2 */ /* XXX STEF XXX GPIO - if (step_type > 1) + if (motor_profile.step_type > 1) { - if (step_type < 3) + if (motor_profile.step_type < 3) { val = effective & ~REG_0x6C_GPIO13; } @@ -546,7 +537,7 @@ static void gl846_init_motor_regs_scan(Genesys_Device* dev, dev->interface->write_register(REG_0x7E, val); } - min_restep=scan_steps/2-1; + min_restep = scan_table.scan_steps / 2 - 1; if (min_restep < 1) { min_restep = 1; } @@ -555,20 +546,20 @@ static void gl846_init_motor_regs_scan(Genesys_Device* dev, r = sanei_genesys_get_address(reg, REG_BWDSTEP); r->value = min_restep; - sanei_genesys_calculate_zmod(use_fast_fed, + sanei_genesys_calculate_zmod(use_fast_fed, scan_exposure_time*ccdlmt*tgtime, - scan_table, - scan_steps*factor, + scan_table.table, + scan_table.scan_steps*factor, feedl, min_restep*factor, &z1, &z2); DBG(DBG_info, "%s: z1 = %d\n", __func__, z1); - reg->set24(REG_0x60, z1 | (static_cast(step_type) << (16 + REG_0x60S_STEPSEL))); + reg->set24(REG_0x60, z1 | (static_cast(motor_profile.step_type) << (16 + REG_0x60S_STEPSEL))); DBG(DBG_info, "%s: z2 = %d\n", __func__, z2); - reg->set24(REG_0x63, z2 | (static_cast(step_type) << (16 + REG_0x63S_FSTPSEL))); + reg->set24(REG_0x63, z2 | (static_cast(motor_profile.step_type) << (16 + REG_0x63S_FSTPSEL))); r = sanei_genesys_get_address (reg, 0x1e); r->value &= 0xf0; /* 0 dummy lines */ @@ -581,19 +572,19 @@ static void gl846_init_motor_regs_scan(Genesys_Device* dev, r->value = 0x7f; r = sanei_genesys_get_address(reg, REG_STEPNO); - r->value = scan_steps; + r->value = scan_table.scan_steps; r = sanei_genesys_get_address(reg, REG_FASTNO); - r->value = scan_steps; + r->value = scan_table.scan_steps; r = sanei_genesys_get_address(reg, REG_FSHDEC); - r->value = scan_steps; + r->value = scan_table.scan_steps; r = sanei_genesys_get_address(reg, REG_FMOVNO); - r->value = fast_steps; + r->value = fast_table.scan_steps; r = sanei_genesys_get_address(reg, REG_FMOVDEC); - r->value = fast_steps; + r->value = fast_table.scan_steps; } @@ -642,7 +633,7 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens r = sanei_genesys_get_address(reg, REG_0x01); r->value &= ~REG_0x01_SCAN; r->value |= REG_0x01_SHDAREA; - if ((session.params.flags & SCAN_FLAG_DISABLE_SHADING) || + if (has_flag(session.params.flags, ScanFlag::DISABLE_SHADING) || (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) { r->value &= ~REG_0x01_DVDSET; @@ -656,7 +647,7 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens r->value &= ~REG_0x03_AVEENB; sanei_genesys_set_lamp_power(dev, sensor, *reg, - !(session.params.flags & SCAN_FLAG_DISABLE_LAMP)); + !has_flag(session.params.flags, ScanFlag::DISABLE_LAMP)); /* BW threshold */ r = sanei_genesys_get_address (reg, 0x2e); @@ -772,13 +763,13 @@ static void gl846_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens exposure_time = get_sensor_profile(dev->model->asic_type, sensor, session.params.xres, 1).exposure_lperiod; - StepType scan_step_type = sanei_genesys_compute_step_type(gl846_motor_profiles, - dev->model->motor_id, - exposure_time); + const auto& motor_profile = sanei_genesys_get_motor_profile(*gl846_motor_profiles, + dev->model->motor_id, + exposure_time); DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, - static_cast(scan_step_type)); + static_cast(motor_profile.step_type)); /* we enable true gray for cis scanners only, and just when doing * scan since color calibration is OK for this mode @@ -792,14 +783,14 @@ static void gl846_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens DBG(DBG_info, "%s: move=%d steps\n", __func__, move); mflags = 0; - if (session.params.flags & SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE) { + if (has_flag(session.params.flags, ScanFlag::DISABLE_BUFFER_FULL_MOVE)) { mflags |= MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE; } - if (session.params.flags & SCAN_FLAG_FEEDING) { + if (has_flag(session.params.flags, ScanFlag::FEEDING)) { mflags |= MOTOR_FLAG_FEED; } - gl846_init_motor_regs_scan(dev, sensor, reg, exposure_time, slope_dpi, scan_step_type, + gl846_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, mflags); @@ -846,7 +837,7 @@ ScanSession CommandSetGl846::calculate_scan_session(const Genesys_Device* dev, session.params.scan_method = settings.scan_method; session.params.scan_mode = settings.scan_mode; session.params.color_filter = settings.color_filter; - session.params.flags = 0; + session.params.flags = ScanFlag::NONE; compute_session(dev, session, sensor); @@ -866,12 +857,6 @@ void CommandSetGl846::set_powersaving(Genesys_Device* dev, int delay /* in minut DBG_HELPER_ARGS(dbg, "delay = %d", delay); } -static void gl846_start_action(Genesys_Device* dev) -{ - DBG_HELPER(dbg); - dev->interface->write_register(0x0f, 0x01); -} - static void gl846_stop_action(Genesys_Device* dev) { DBG_HELPER(dbg); @@ -955,11 +940,7 @@ void CommandSetGl846::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens r = sanei_genesys_get_address (reg, REG_0x01); r->value = val; - if (start_motor) { - dev->interface->write_register(REG_0x0F, 1); - } else { - dev->interface->write_register(REG_0x0F, 0); - } + scanner_start_action(*dev, start_motor); } @@ -1035,9 +1016,9 @@ void CommandSetGl846::slow_back_home(Genesys_Device* dev, bool wait_until_home) session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::RED; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl846_init_scan_regs(dev, sensor, &local_reg, session); @@ -1054,7 +1035,7 @@ void CommandSetGl846::slow_back_home(Genesys_Device* dev, bool wait_until_home) dev->interface->write_registers(local_reg); try { - gl846_start_action(dev); + scanner_start_action(*dev, true); } catch (...) { try { gl846_stop_action(dev); @@ -1133,9 +1114,9 @@ void CommandSetGl846::search_start_position(Genesys_Device* dev) const session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::GREEN; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl846_init_scan_regs(dev, sensor, &local_reg, session); @@ -1201,10 +1182,10 @@ void CommandSetGl846::init_regs_for_coarse_calibration(Genesys_Device* dev, 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl846_init_scan_regs(dev, sensor, ®s, session); @@ -1244,10 +1225,10 @@ static void gl846_feed(Genesys_Device* dev, unsigned int steps) 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_FEEDING | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::FEEDING | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl846_init_scan_regs(dev, sensor, &local_reg, session); @@ -1268,7 +1249,7 @@ static void gl846_feed(Genesys_Device* dev, unsigned int steps) dev->interface->write_registers(local_reg); try { - gl846_start_action(dev); + scanner_start_action(*dev, true); } catch (...) { try { gl846_stop_action(dev); @@ -1338,10 +1319,10 @@ void CommandSetGl846::init_regs_for_shading(Genesys_Device* dev, const Genesys_S 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::DISABLE_BUFFER_FULL_MOVE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl846_init_scan_regs(dev, sensor, ®s, session); @@ -1423,7 +1404,7 @@ void CommandSetGl846::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sens session.params.scan_mode = dev->settings.scan_mode; session.params.color_filter = dev->settings.color_filter; // backtracking isn't handled well, so don't enable it - session.params.flags = SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE; + session.params.flags = ScanFlag::DISABLE_BUFFER_FULL_MOVE; compute_session(dev, session, sensor); gl846_init_scan_regs(dev, sensor, &dev->reg, session); @@ -1556,10 +1537,10 @@ SensorExposure CommandSetGl846::led_calibration(Genesys_Device* dev, const Genes 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl846_init_scan_regs(dev, sensor, ®s, session); @@ -1889,8 +1870,8 @@ void CommandSetGl846::search_strip(Genesys_Device* dev, const Genesys_Sensor& se session.params.channels = channels; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::RED; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA; compute_session(dev, session, sensor); gl846_init_scan_regs(dev, sensor, &local_reg, session); @@ -2116,10 +2097,10 @@ void CommandSetGl846::offset_calibration(Genesys_Device* dev, const Genesys_Sens 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl846_init_scan_regs(dev, sensor, ®s, session); @@ -2270,10 +2251,10 @@ void CommandSetGl846::coarse_gain_calibration(Genesys_Device* dev, const Genesys 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); try { diff --git a/backend/genesys/gl847.cpp b/backend/genesys/gl847.cpp index 17b3c885b..c9e67417e 100644 --- a/backend/genesys/gl847.cpp +++ b/backend/genesys/gl847.cpp @@ -317,6 +317,9 @@ static void gl847_send_slope_table(Genesys_Device* dev, int table_nr, 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()); } @@ -402,9 +405,9 @@ void CommandSetGl847::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, static void gl847_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, Genesys_Register_Set* reg, + const Motor_Profile& motor_profile, unsigned int scan_exposure_time, unsigned scan_yres, - StepType step_type, unsigned int scan_lines, unsigned int scan_dummy, unsigned int feed_steps, @@ -412,13 +415,11 @@ static void gl847_init_motor_regs_scan(Genesys_Device* dev, { DBG_HELPER_ARGS(dbg, "scan_exposure_time=%d, can_yres=%d, step_type=%d, scan_lines=%d, " "scan_dummy=%d, feed_steps=%d, flags=%x", - scan_exposure_time, scan_yres, static_cast(step_type), scan_lines, - scan_dummy, feed_steps, flags); + scan_exposure_time, scan_yres, static_cast(motor_profile.step_type), + scan_lines, scan_dummy, feed_steps, flags); int use_fast_fed; unsigned int fast_dpi; - std::vector scan_table; - std::vector fast_table; - int scan_steps, fast_steps, factor; + int factor; unsigned int feedl, dist; GenesysRegister *r; uint32_t z1, z2; @@ -461,48 +462,37 @@ static void gl847_init_motor_regs_scan(Genesys_Device* dev, } /* scan and backtracking slope table */ - sanei_genesys_slope_table(scan_table, - &scan_steps, - scan_yres, - scan_exposure_time, - dev->motor.base_ydpi, - step_type, - factor, - dev->model->motor_id, - gl847_motor_profiles); - gl847_send_slope_table(dev, SCAN_TABLE, scan_table, scan_steps * factor); - gl847_send_slope_table(dev, BACKTRACK_TABLE, scan_table, scan_steps * factor); + auto scan_table = sanei_genesys_slope_table(scan_yres, scan_exposure_time, dev->motor.base_ydpi, + factor, motor_profile); + gl847_send_slope_table(dev, SCAN_TABLE, scan_table.table, scan_table.scan_steps * factor); + gl847_send_slope_table(dev, BACKTRACK_TABLE, scan_table.table, scan_table.scan_steps * factor); /* fast table */ fast_dpi=sanei_genesys_get_lowest_ydpi(dev); - StepType fast_step_type = step_type; - if (static_cast(step_type) >= static_cast(StepType::QUARTER)) { + StepType fast_step_type = motor_profile.step_type; + if (static_cast(motor_profile.step_type) >= static_cast(StepType::QUARTER)) { fast_step_type = StepType::QUARTER; } - sanei_genesys_slope_table(fast_table, - &fast_steps, - fast_dpi, - scan_exposure_time, - dev->motor.base_ydpi, - fast_step_type, - factor, - dev->model->motor_id, - gl847_motor_profiles); + Motor_Profile fast_motor_profile = motor_profile; + fast_motor_profile.step_type = fast_step_type; - /* manual override of high start value */ - fast_table[0]=fast_table[1]; + auto fast_table = sanei_genesys_slope_table(fast_dpi, scan_exposure_time, dev->motor.base_ydpi, + factor, fast_motor_profile); - gl847_send_slope_table(dev, STOP_TABLE, fast_table, fast_steps * factor); - gl847_send_slope_table(dev, FAST_TABLE, fast_table, fast_steps * factor); - gl847_send_slope_table(dev, HOME_TABLE, fast_table, fast_steps * factor); + // manual override of high start value + fast_table.table[0] = fast_table.table[1]; + + gl847_send_slope_table(dev, STOP_TABLE, fast_table.table, fast_table.scan_steps * factor); + gl847_send_slope_table(dev, FAST_TABLE, fast_table.table, fast_table.scan_steps * factor); + gl847_send_slope_table(dev, HOME_TABLE, fast_table.table, fast_table.scan_steps * factor); /* correct move distance by acceleration and deceleration amounts */ feedl=feed_steps; if (use_fast_fed) { feedl <<= static_cast(fast_step_type); - dist=(scan_steps+2*fast_steps)*factor; + dist = (scan_table.scan_steps + 2 * fast_table.scan_steps) * factor; /* TODO read and decode REG_0xAB */ r = sanei_genesys_get_address (reg, 0x5e); dist += (r->value & 31); @@ -512,12 +502,12 @@ static void gl847_init_motor_regs_scan(Genesys_Device* dev, } else { - feedl <<= static_cast(step_type); - dist=scan_steps*factor; + feedl <<= static_cast(motor_profile.step_type); + dist=scan_table.scan_steps*factor; if (flags & MOTOR_FLAG_FEED) dist *=2; } - DBG(DBG_io2, "%s: scan steps=%d\n", __func__, scan_steps); + DBG(DBG_io2, "%s: scan steps=%d\n", __func__, scan_table.scan_steps); DBG(DBG_io2, "%s: acceleration distance=%d\n", __func__, dist); /* check for overflow */ @@ -541,9 +531,9 @@ static void gl847_init_motor_regs_scan(Genesys_Device* dev, // if quarter step, bipolar Vref2 - if (step_type == StepType::QUARTER) { + if (motor_profile.step_type == StepType::QUARTER) { val = effective & ~REG_0x6C_GPIO13; - } else if (static_cast(step_type) > static_cast(StepType::QUARTER)) { + } else if (static_cast(motor_profile.step_type) > static_cast(StepType::QUARTER)) { val = effective | REG_0x6C_GPIO13; } else { val = effective; @@ -555,7 +545,7 @@ static void gl847_init_motor_regs_scan(Genesys_Device* dev, val = effective | REG_0x6C_GPIO10; dev->interface->write_register(REG_0x6C, val); - min_restep=scan_steps/2-1; + min_restep = scan_table.scan_steps / 2 - 1; if (min_restep < 1) { min_restep = 1; } @@ -564,20 +554,20 @@ static void gl847_init_motor_regs_scan(Genesys_Device* dev, r = sanei_genesys_get_address(reg, REG_BWDSTEP); r->value = min_restep; - sanei_genesys_calculate_zmod(use_fast_fed, + sanei_genesys_calculate_zmod(use_fast_fed, scan_exposure_time*ccdlmt*tgtime, - scan_table, - scan_steps*factor, + scan_table.table, + scan_table.scan_steps*factor, feedl, min_restep*factor, &z1, &z2); DBG(DBG_info, "%s: z1 = %d\n", __func__, z1); - reg->set24(REG_0x60, z1 | (static_cast(step_type) << (16+REG_0x60S_STEPSEL))); + reg->set24(REG_0x60, z1 | (static_cast(motor_profile.step_type) << (16+REG_0x60S_STEPSEL))); DBG(DBG_info, "%s: z2 = %d\n", __func__, z2); - reg->set24(REG_0x63, z2 | (static_cast(step_type) << (16+REG_0x63S_FSTPSEL))); + reg->set24(REG_0x63, z2 | (static_cast(motor_profile.step_type) << (16+REG_0x63S_FSTPSEL))); r = sanei_genesys_get_address (reg, 0x1e); r->value &= 0xf0; /* 0 dummy lines */ @@ -590,19 +580,19 @@ static void gl847_init_motor_regs_scan(Genesys_Device* dev, r->value = REG_0x68_FASTPWM; r = sanei_genesys_get_address(reg, REG_STEPNO); - r->value = scan_steps; + r->value = scan_table.scan_steps; r = sanei_genesys_get_address(reg, REG_FASTNO); - r->value = scan_steps; + r->value = scan_table.scan_steps; r = sanei_genesys_get_address(reg, REG_FSHDEC); - r->value = scan_steps; + r->value = scan_table.scan_steps; r = sanei_genesys_get_address(reg, REG_FMOVNO); - r->value = fast_steps; + r->value = fast_table.scan_steps; r = sanei_genesys_get_address(reg, REG_FMOVDEC); - r->value = fast_steps; + r->value = fast_table.scan_steps; } @@ -652,7 +642,7 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens r->value &= ~REG_0x01_SCAN; r->value |= REG_0x01_SHDAREA; - if ((session.params.flags & SCAN_FLAG_DISABLE_SHADING) || + if (has_flag(session.params.flags, ScanFlag::DISABLE_SHADING) || (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) { r->value &= ~REG_0x01_DVDSET; @@ -666,7 +656,7 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens r->value &= ~REG_0x03_AVEENB; sanei_genesys_set_lamp_power(dev, sensor, *reg, - !(session.params.flags & SCAN_FLAG_DISABLE_LAMP)); + !has_flag(session.params.flags, ScanFlag::DISABLE_LAMP)); /* BW threshold */ r = sanei_genesys_get_address (reg, 0x2e); @@ -783,12 +773,13 @@ static void gl847_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens exposure_time = get_sensor_profile(dev->model->asic_type, sensor, session.params.xres, 1).exposure_lperiod; - StepType scan_step_type = sanei_genesys_compute_step_type(gl847_motor_profiles, - dev->model->motor_id, - exposure_time); + const auto& motor_profile = sanei_genesys_get_motor_profile(*gl847_motor_profiles, + dev->model->motor_id, + exposure_time); DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); - DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, static_cast(scan_step_type)); + DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, + static_cast(motor_profile.step_type)); /* we enable true gray for cis scanners only, and just when doing * scan since color calibration is OK for this mode @@ -799,14 +790,14 @@ static void gl847_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens DBG(DBG_info, "%s: move=%d steps\n", __func__, move); mflags=0; - if (session.params.flags & SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE) { + if (has_flag(session.params.flags, ScanFlag::DISABLE_BUFFER_FULL_MOVE)) { mflags |= MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE; } - if (session.params.flags & SCAN_FLAG_FEEDING) { + if (has_flag(session.params.flags, ScanFlag::FEEDING)) { mflags |= MOTOR_FLAG_FEED; } - gl847_init_motor_regs_scan(dev, sensor, reg, exposure_time, slope_dpi, scan_step_type, + gl847_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, mflags); @@ -851,7 +842,7 @@ ScanSession CommandSetGl847::calculate_scan_session(const Genesys_Device* dev, session.params.scan_method = settings.scan_method; session.params.scan_mode = settings.scan_mode; session.params.color_filter = settings.color_filter; - session.params.flags = 0; + session.params.flags = ScanFlag::NONE; compute_session(dev, session, sensor); @@ -871,12 +862,6 @@ void CommandSetGl847::set_powersaving(Genesys_Device* dev, int delay /* in minut DBG_HELPER_ARGS(dbg, "delay = %d", delay); } -static void gl847_start_action(Genesys_Device* dev) -{ - DBG_HELPER(dbg); - dev->interface->write_register(0x0f, 0x01); -} - static void gl847_stop_action(Genesys_Device* dev) { DBG_HELPER(dbg); @@ -962,11 +947,7 @@ void CommandSetGl847::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens r = sanei_genesys_get_address (reg, REG_0x01); r->value = val; - if (start_motor) { - dev->interface->write_register(REG_0x0F, 1); - } else { - dev->interface->write_register(REG_0x0F, 0); - } + scanner_start_action(*dev, start_motor); } @@ -1080,9 +1061,9 @@ void CommandSetGl847::slow_back_home(Genesys_Device* dev, bool wait_until_home) session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::RED; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl847_init_scan_regs(dev, sensor, &local_reg, session); @@ -1099,7 +1080,7 @@ void CommandSetGl847::slow_back_home(Genesys_Device* dev, bool wait_until_home) dev->interface->write_registers(local_reg); try { - gl847_start_action(dev); + scanner_start_action(*dev, true); } catch (...) { catch_all_exceptions(__func__, [&]() { gl847_stop_action(dev); }); // restore original registers @@ -1176,9 +1157,9 @@ void CommandSetGl847::search_start_position(Genesys_Device* dev) const session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::GREEN; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl847_init_scan_regs(dev, sensor, &local_reg, session); @@ -1244,10 +1225,10 @@ void CommandSetGl847::init_regs_for_coarse_calibration(Genesys_Device* dev, 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl847_init_scan_regs(dev, sensor, ®s, session); @@ -1286,10 +1267,10 @@ static void gl847_feed(Genesys_Device* dev, unsigned int steps) 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_FEEDING | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::FEEDING | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl847_init_scan_regs(dev, sensor, &local_reg, session); @@ -1311,7 +1292,7 @@ static void gl847_feed(Genesys_Device* dev, unsigned int steps) dev->interface->write_registers(local_reg); try { - gl847_start_action(dev); + scanner_start_action(*dev, true); } catch (...) { catch_all_exceptions(__func__, [&]() { gl847_stop_action(dev); }); // restore original registers @@ -1371,10 +1352,10 @@ void CommandSetGl847::init_regs_for_shading(Genesys_Device* dev, const Genesys_S 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::DISABLE_BUFFER_FULL_MOVE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl847_init_scan_regs(dev, sensor, ®s, session); @@ -1455,7 +1436,7 @@ void CommandSetGl847::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sens session.params.scan_mode = dev->settings.scan_mode; session.params.color_filter = dev->settings.color_filter; // backtracking isn't handled well, so don't enable it - session.params.flags = SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE; + session.params.flags = ScanFlag::DISABLE_BUFFER_FULL_MOVE; compute_session(dev, session, sensor); gl847_init_scan_regs(dev, sensor, &dev->reg, session); @@ -1589,10 +1570,10 @@ SensorExposure CommandSetGl847::led_calibration(Genesys_Device* dev, const Genes 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl847_init_scan_regs(dev, sensor, ®s, session); @@ -1953,8 +1934,8 @@ void CommandSetGl847::search_strip(Genesys_Device* dev, const Genesys_Sensor& se session.params.scan_method = dev->settings.scan_method; session.params.scan_mode = ScanColorMode::GRAY; session.params.color_filter = ColorFilter::RED; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA; compute_session(dev, session, sensor); size = pixels * channels * lines * (session.params.depth / 8); @@ -2181,10 +2162,10 @@ void CommandSetGl847::offset_calibration(Genesys_Device* dev, const Genesys_Sens 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); gl847_init_scan_regs(dev, sensor, ®s, session); @@ -2334,10 +2315,10 @@ void CommandSetGl847::coarse_gain_calibration(Genesys_Device* dev, const Genesys 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 = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; compute_session(dev, session, sensor); try { diff --git a/backend/genesys/low.cpp b/backend/genesys/low.cpp index f20f36fdd..53ef44cd6 100644 --- a/backend/genesys/low.cpp +++ b/backend/genesys/low.cpp @@ -600,7 +600,7 @@ void sanei_genesys_set_motor_power(Genesys_Register_Set& regs, bool set) bool should_enable_gamma(const ScanSession& session, const Genesys_Sensor& sensor) { - if (session.params.flags & SCAN_FLAG_DISABLE_GAMMA) { + if ((session.params.flags & ScanFlag::DISABLE_GAMMA) != ScanFlag::NONE) { return false; } if (sensor.gamma[0] == 1.0f || sensor.gamma[1] == 1.0f || sensor.gamma[2] == 1.0f) { @@ -851,7 +851,7 @@ void compute_session_pixel_offsets(const Genesys_Device* dev, ScanSession& s, // startx cannot be below dummy pixel value s.pixel_startx = sensor.dummy_pixel; - if ((s.params.flags & SCAN_FLAG_USE_XCORRECTION) && sensor.ccd_start_xoffset > 0) { + if (has_flag(s.params.flags, ScanFlag::USE_XCORRECTION) && sensor.ccd_start_xoffset > 0) { s.pixel_startx = sensor.ccd_start_xoffset; } s.pixel_startx += s.params.startx; @@ -1045,7 +1045,7 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se if (dev->model->asic_type == AsicType::GL843) { if ((s.params.yres > 1200) && // FIXME: maybe ccd_size_divisor is the one that controls this? - ((s.params.flags & SCAN_FLAG_IGNORE_LINE_DISTANCE) == 0) && + !has_flag(s.params.flags, ScanFlag::IGNORE_LINE_DISTANCE) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) { s.num_staggered_lines = (4 * s.params.yres) / dev->motor.base_ydpi; @@ -1068,7 +1068,7 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se s.color_shift_lines_b = (s.color_shift_lines_b * s.params.yres) / dev->motor.base_ydpi; s.max_color_shift_lines = 0; - if (s.params.channels > 1 && !(s.params.flags & SCAN_FLAG_IGNORE_LINE_DISTANCE)) { + if (s.params.channels > 1 && !has_flag(s.params.flags, ScanFlag::IGNORE_LINE_DISTANCE)) { s.max_color_shift_lines = std::max(s.color_shift_lines_r, std::max(s.color_shift_lines_g, s.color_shift_lines_b)); } @@ -1182,7 +1182,7 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se { // no 16 bit gamma for this ASIC if (s.params.depth == 16) { - s.params.flags |= SCAN_FLAG_DISABLE_GAMMA; + s.params.flags |= ScanFlag::DISABLE_GAMMA; } } @@ -1543,6 +1543,28 @@ void sanei_genesys_asic_init(Genesys_Device* dev, bool /*max_regs*/) dev->cmd_set->set_powersaving(dev, 15); } +void scanner_start_action(Genesys_Device& dev, bool start_motor) +{ + DBG_HELPER(dbg); + switch (dev.model->asic_type) { + case AsicType::GL646: + case AsicType::GL841: + case AsicType::GL843: + case AsicType::GL845: + case AsicType::GL846: + case AsicType::GL847: + case AsicType::GL124: + break; + default: + throw SaneException("Unsupported chip"); + } + + if (start_motor) { + dev.interface->write_register(0x0f, 0x01); + } else { + dev.interface->write_register(0x0f, 0); + } +} void sanei_genesys_set_dpihw(Genesys_Register_Set& regs, const Genesys_Sensor& sensor, unsigned dpihw) @@ -1639,19 +1661,16 @@ void sanei_genesys_wait_for_home(Genesys_Device* dev) * @param exposure exposure time * @return a pointer to a Motor_Profile struct */ -Motor_Profile* sanei_genesys_get_motor_profile(Motor_Profile *motors, MotorId motor_id, - int exposure) +const Motor_Profile& sanei_genesys_get_motor_profile(const std::vector& motors, + MotorId motor_id, int exposure) { - unsigned int i; int idx; - i=0; idx=-1; - while(motors[i].exposure!=0) - { + for (std::size_t i = 0; i < motors.size(); ++i) { // exact match if (motors[i].motor_id == motor_id && motors[i].exposure==exposure) { - return &(motors[i]); + return motors[i]; } // closest match @@ -1675,7 +1694,6 @@ Motor_Profile* sanei_genesys_get_motor_profile(Motor_Profile *motors, MotorId mo } } } - i++; } /* default fallback */ @@ -1685,23 +1703,7 @@ Motor_Profile* sanei_genesys_get_motor_profile(Motor_Profile *motors, MotorId mo idx=0; } - return &(motors[idx]); -} - -/**@brief compute motor step type to use - * compute the step type (full, half, quarter, ...) to use based - * on target resolution - * @return 0 for full step - * 1 for half step - * 2 for quarter step - * 3 for eighth step - */ -StepType sanei_genesys_compute_step_type(Motor_Profile* motors, MotorId motor_id, int exposure) -{ -Motor_Profile *profile; - - profile = sanei_genesys_get_motor_profile(motors, motor_id, exposure); - return profile->step_type; + return motors[idx]; } /** @brief generate slope table @@ -1712,60 +1714,53 @@ Motor_Profile *profile; * @param dpi desired motor resolution * @param exposure exposure used * @param base_dpi base resolution of the motor - * @param step_type step type used for scan * @param factor shrink factor for the slope - * @param motor_type motor id - * @param motors motor profile database + * @param motor_profile motor profile */ -int sanei_genesys_slope_table(std::vector& slope, - int* steps, int dpi, int exposure, int base_dpi, StepType step_type, - int factor, MotorId motor_id, Motor_Profile* motors) +MotorSlopeTable sanei_genesys_slope_table(int dpi, int exposure, int base_dpi, + int factor, const Motor_Profile& motor_profile) { + MotorSlopeTable table; int sum, i; uint16_t target,current; -Motor_Profile *profile; - unsigned step_shift = static_cast(step_type); - slope.clear(); + unsigned step_shift = static_cast(motor_profile.step_type); + table.table.clear(); /* required speed */ target = ((exposure * dpi) / base_dpi) >> step_shift; DBG (DBG_io2, "%s: exposure=%d, dpi=%d, target=%d\n", __func__, exposure, dpi, target); /* fill result with target speed */ - slope.resize(SLOPE_TABLE_SIZE, target); - - profile=sanei_genesys_get_motor_profile(motors, motor_id, exposure); + table.table.resize(SLOPE_TABLE_SIZE, target); /* use profile to build table */ i=0; sum=0; - /* first step is always used unmodified */ - current=profile->table[0]; + // first step is always used unmodified + current = motor_profile.table[0]; - /* loop on profile copying and apply step type */ - while(profile->table[i]!=0 && current>=target) - { - slope[i]=current; - sum+=slope[i]; - i++; - current = profile->table[i] >> step_shift; - } + // loop on profile copying and apply step type + while (motor_profile.table[i] != 0 && current >= target) { + table.table[i]=current; + sum += table.table[i]; + i++; + current = motor_profile.table[i] >> step_shift; + } /* ensure last step is required speed in case profile doesn't contain it */ if(current!=0 && currenttable[i]==0 && DBG_LEVEL >= DBG_warn && current>target) - { + if (motor_profile.table[i] == 0 && DBG_LEVEL >= DBG_warn && current > target) { DBG (DBG_warn,"%s: short slope table, failed to reach %d. target too low ?\n",__func__,target); - } + } if(i<3 && DBG_LEVEL >= DBG_warn) { DBG (DBG_warn,"%s: short slope table, failed to reach %d. target too high ?\n",__func__,target); @@ -1774,22 +1769,23 @@ Motor_Profile *profile; /* align on factor */ while(i%factor!=0) { - slope[i+1]=slope[i]; - sum+=slope[i]; + table.table[i+1] = table.table[i]; + sum += table.table[i]; i++; } /* ensure minimal slope size */ while(i<2*factor) { - slope[i+1]=slope[i]; - sum+=slope[i]; + table.table[i+1] = table.table[i]; + sum += table.table[i]; i++; } - // return used steps and taken time - *steps=i/factor; - return sum; + // return used steps and taken time + table.scan_steps = i / factor; + table.pixeltime_sum = sum; + return table; } /** @brief returns the lowest possible ydpi for the device @@ -2002,23 +1998,4 @@ void sanei_genesys_load_lut(unsigned char* lut, } } -static std::unique_ptr>> s_functions_run_at_backend_exit; - -void add_function_to_run_at_backend_exit(std::function function) -{ - if (!s_functions_run_at_backend_exit) - s_functions_run_at_backend_exit.reset(new std::vector>()); - s_functions_run_at_backend_exit->push_back(std::move(function)); -} - -void run_functions_at_backend_exit() -{ - for (auto it = s_functions_run_at_backend_exit->rbegin(); - it != s_functions_run_at_backend_exit->rend(); ++it) - { - (*it)(); - } - s_functions_run_at_backend_exit.reset(); -} - } // namespace genesys diff --git a/backend/genesys/low.h b/backend/genesys/low.h index b8b3a3ecf..312efe643 100644 --- a/backend/genesys/low.h +++ b/backend/genesys/low.h @@ -88,6 +88,7 @@ #include "sensor.h" #include "serialize.h" #include "settings.h" +#include "static_init.h" #include "register.h" #include @@ -234,24 +235,13 @@ struct Motor_Profile uint32_t *table; // 0-terminated slope table at full step (i.e. step_type == 0) }; -extern Motor_Profile gl843_motor_profiles[]; -extern Motor_Profile gl846_motor_profiles[]; -extern Motor_Profile gl847_motor_profiles[]; -extern Motor_Profile gl124_motor_profiles[]; +extern StaticInit> gl843_motor_profiles; +extern StaticInit> gl846_motor_profiles; +extern StaticInit> gl847_motor_profiles; +extern StaticInit> gl124_motor_profiles; -#define SLOPE_TABLE_SIZE 1024 +constexpr unsigned SLOPE_TABLE_SIZE = 1024; -#define SCAN_FLAG_SINGLE_LINE 0x001 -#define SCAN_FLAG_DISABLE_SHADING 0x002 -#define SCAN_FLAG_DISABLE_GAMMA 0x004 -#define SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE 0x008 -#define SCAN_FLAG_IGNORE_LINE_DISTANCE 0x010 -#define SCAN_FLAG_DISABLE_LAMP 0x040 -#define SCAN_FLAG_CALIBRATION 0x100 -#define SCAN_FLAG_FEEDING 0x200 -#define SCAN_FLAG_USE_XPA 0x400 -#define SCAN_FLAG_ENABLE_LEDADD 0x800 -#define SCAN_FLAG_USE_XCORRECTION 0x1000 #define MOTOR_FLAG_AUTO_GO_HOME 0x01 #define MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE 0x02 #define MOTOR_FLAG_FEED 0x04 @@ -336,7 +326,7 @@ extern void sanei_genesys_set_buffer_address(Genesys_Device* dev, uint32_t addr) unsigned sanei_genesys_get_bulk_max_size(AsicType asic_type); -SANE_Int sanei_genesys_exposure_time2(Genesys_Device * dev, float ydpi, int step_type, +SANE_Int sanei_genesys_exposure_time2(Genesys_Device * dev, float ydpi, StepType step_type, int endpixel, int led_exposure); SANE_Int sanei_genesys_generate_slope_table(std::vector& slope_table, unsigned int max_steps, @@ -345,15 +335,11 @@ SANE_Int sanei_genesys_generate_slope_table(std::vector& slope_table, unsigned int steps, double g, unsigned int *used_steps, unsigned int *vfinal); -SANE_Int sanei_genesys_create_slope_table(Genesys_Device * dev, std::vector& slope_table, - int steps, int step_type, int exposure_time, - bool same_speed, double yres); - -SANE_Int sanei_genesys_create_slope_table3(Genesys_Device * dev, +SANE_Int sanei_genesys_create_slope_table3(const Genesys_Motor& motor, std::vector& slope_table, int max_step, unsigned int use_steps, - int step_type, int exposure_time, - double yres, + StepType step_type, int exposure_time, + unsigned yres, unsigned int *used_steps, unsigned int *final_exposure); @@ -425,14 +411,13 @@ extern void sanei_genesys_wait_for_home(Genesys_Device* dev); extern void sanei_genesys_asic_init(Genesys_Device* dev, bool cold); -Motor_Profile* sanei_genesys_get_motor_profile(Motor_Profile *motors, MotorId motor_id, - int exposure); +void scanner_start_action(Genesys_Device& dev, bool start_motor); -StepType sanei_genesys_compute_step_type(Motor_Profile* motors, MotorId motor_id, int exposure); +const Motor_Profile& sanei_genesys_get_motor_profile(const std::vector& motors, + MotorId motor_id, int exposure); -int sanei_genesys_slope_table(std::vector& slope, int *steps, int dpi, int exposure, - int base_dpi, StepType step_type, int factor, MotorId motor_id, - Motor_Profile *motors); +MotorSlopeTable sanei_genesys_slope_table(int dpi, int exposure, int base_dpi, + int factor, const Motor_Profile& motor_profile); /** @brief find lowest motor resolution for the device. * Parses the resolution list for motor and @@ -522,40 +507,6 @@ inline T clamp(const T& value, const T& lo, const T& hi) /* ASIC specific functions declarations */ /*---------------------------------------------------------------------------*/ -void add_function_to_run_at_backend_exit(std::function function); - -// calls functions added via add_function_to_run_at_backend_exit() in reverse order of being -// added. -void run_functions_at_backend_exit(); - -template -class StaticInit { -public: - StaticInit() = default; - StaticInit(const StaticInit&) = delete; - StaticInit& operator=(const StaticInit&) = delete; - - template - void init(Args&& ... args) - { - ptr_ = std::unique_ptr(new T(std::forward(args)...)); - add_function_to_run_at_backend_exit([this](){ deinit(); }); - } - - void deinit() - { - ptr_.reset(); - } - - const T* operator->() const { return ptr_.get(); } - T* operator->() { return ptr_.get(); } - const T& operator*() const { return *ptr_.get(); } - T& operator*() { return *ptr_.get(); } - -private: - std::unique_ptr ptr_; -}; - extern StaticInit> s_sensors; extern StaticInit s_fallback_sensor_profile_gl124; extern StaticInit s_fallback_sensor_profile_gl846; @@ -569,6 +520,7 @@ void genesys_init_sensor_tables(); void genesys_init_frontend_tables(); void genesys_init_gpo_tables(); void genesys_init_motor_tables(); +void genesys_init_motor_profile_tables(); void genesys_init_usb_device_tables(); template diff --git a/backend/genesys/motor.cpp b/backend/genesys/motor.cpp index f6c5fdd66..2a0a5e767 100644 --- a/backend/genesys/motor.cpp +++ b/backend/genesys/motor.cpp @@ -45,12 +45,85 @@ #include "motor.h" #include "utilities.h" +#include namespace genesys { -std::ostream& operator<<(std::ostream& out, const Genesys_Motor_Slope& slope) +unsigned MotorSlope::get_table_step_shifted(unsigned step, StepType step_type) const +{ + // first two steps are always equal to the initial speed + if (step < 2) { + return initial_speed_w >> static_cast(step_type); + } + step--; + + float initial_speed_v = 1.0f / initial_speed_w; + float speed_v = std::sqrt(initial_speed_v * initial_speed_v + 2 * acceleration * step); + return static_cast(1.0f / speed_v) >> static_cast(step_type); +} + +MotorSlopeTable create_slope_table(const MotorSlope& slope, unsigned target_speed_w, + StepType step_type, unsigned steps_alignment, + unsigned min_size) +{ + DBG_HELPER_ARGS(dbg, "target_speed_w: %d, step_type: %d, steps_alignment: %d, min_size: %d", + target_speed_w, static_cast(step_type), steps_alignment, min_size); + MotorSlopeTable table; + + unsigned step_shift = static_cast(step_type); + + unsigned target_speed_shifted_w = target_speed_w >> step_shift; + unsigned max_speed_shifted_w = slope.max_speed_w >> step_shift; + + if (target_speed_shifted_w < max_speed_shifted_w) { + dbg.log(DBG_warn, "failed to reach target speed"); + } + + unsigned final_speed = std::max(target_speed_shifted_w, max_speed_shifted_w); + + table.table.reserve(MotorSlopeTable::SLOPE_TABLE_SIZE); + + while (true) { + unsigned current = slope.get_table_step_shifted(table.table.size(), step_type); + if (current <= final_speed) { + break; + } + table.table.push_back(current); + table.pixeltime_sum += current; + } + + // make sure the target speed (or the max speed if target speed is too high) is present in + // the table + table.table.push_back(final_speed); + table.pixeltime_sum += table.table.back(); + + // fill the table up to the specified size + while (table.table.size() % steps_alignment != 0 || table.table.size() < min_size) { + table.table.push_back(table.table.back()); + table.pixeltime_sum += table.table.back(); + } + + table.scan_steps = table.table.size(); + + // fill the rest of the table with the final speed + table.table.resize(MotorSlopeTable::SLOPE_TABLE_SIZE, final_speed); + + return table; +} + +std::ostream& operator<<(std::ostream& out, const MotorSlope& slope) { out << "Genesys_Motor_Slope{\n" + << " initial_speed_w: " << slope.initial_speed_w << '\n' + << " max_speed_w: " << slope.max_speed_w << '\n' + << " a: " << slope.acceleration << '\n' + << '}'; + return out; +} + +std::ostream& operator<<(std::ostream& out, const MotorSlopeLegacy& slope) +{ + out << "MotorSlopeLegacy{\n" << " maximum_start_speed: " << slope.maximum_start_speed << '\n' << " maximum_speed: " << slope.maximum_speed << '\n' << " minimum_steps: " << slope.minimum_steps << '\n' @@ -59,13 +132,22 @@ std::ostream& operator<<(std::ostream& out, const Genesys_Motor_Slope& slope) return out; } +std::ostream& operator<<(std::ostream& out, const Genesys_Motor_Slope& slope) +{ + if (slope.type() == Genesys_Motor_Slope::LEGACY) { + out << slope.legacy(); + } else { + out << slope.physical(); + } + return out; +} + std::ostream& operator<<(std::ostream& out, const Genesys_Motor& motor) { out << "Genesys_Motor{\n" << " id: " << static_cast(motor.id) << '\n' << " base_ydpi: " << motor.base_ydpi << '\n' << " optical_ydpi: " << motor.optical_ydpi << '\n' - << " max_step_type: " << motor.max_step_type << '\n' << " slopes: " << format_indent_braced_list(4, format_vector_indent_braced(4, "Genesys_Motor_Slope", motor.slopes)) diff --git a/backend/genesys/motor.h b/backend/genesys/motor.h index da0fc3bdb..681844cba 100644 --- a/backend/genesys/motor.h +++ b/backend/genesys/motor.h @@ -50,17 +50,72 @@ namespace genesys { -struct Genesys_Motor_Slope -{ - Genesys_Motor_Slope() = default; - Genesys_Motor_Slope(int p_maximum_start_speed, int p_maximum_speed, int p_minimum_steps, - float p_g) : - maximum_start_speed(p_maximum_start_speed), - maximum_speed(p_maximum_speed), - minimum_steps(p_minimum_steps), - g(p_g) - {} +/* Describes a motor acceleration curve. + The curves are described in two ways: legacy and physical modes. + + LEGACY mode + + The legacy mode is to be removed and described the motor slope as a purely mathematical + power law formula: + + v(step) = sl.maximum_start_speed * (1 - pow(q, sl.g)) + sl.maximum_speed * pow(q, sl.g) (1) + + where `q = step_number / s.minimum_steps`, `sl` is the slope config. + + + PHYSICAL mode + + Definitions: + v - speed in steps per pixeltime + w - speed in pixel times per step. w = 1 / v + a - acceleration in steps per pixeltime squared + s - distance travelled in steps + t - time in pixeltime + + The physical mode defines the curve in physical quantities. We asssume that the scanner head + accelerates from standstill to the target speed uniformly. Then: + + v(t) = v(0) + a * t (2) + + Where `a` is acceleration, `t` is time. Also we can calculate the travelled distance `s`: + + s(t) = v(0) * t + a * t^2 / 2 (3) + + The actual motor slope is defined as the duration of each motor step. That means we need to + define speed in terms of travelled distance. + + Solving (3) for `t` gives: + + sqrt( v(0)^2 + 2 * a * s ) - v(0) + t(s) = --------------------------------- (4) + a + + Combining (4) and (2) will yield: + + v(s) = sqrt( v(0)^2 + 2 * a * s ) (5) + + The data in the slope struct MotorSlope corresponds to the above in the following way: + + maximum_start_speed is `w(0) = 1/v(0)` + + maximum_speed is defines maximum speed which should not be exceeded + + minimum_steps is not used + + g is `a` + + Given the start and target speeds on a known motor curve, `a` can be computed as follows: + + v(t1)^2 - v(t0)^2 + a = ----------------- (6) + 2 * s + + Here `v(t0)` and `v(t1)` are the start and target speeds and `s` is the number of step required + to reach the target speeds. +*/ +struct MotorSlopeLegacy +{ // maximum speed allowed when accelerating from standstill. Unit: pixeltime/step int maximum_start_speed = 0; // maximum speed allowed. Unit: pixeltime/step @@ -68,20 +123,70 @@ struct Genesys_Motor_Slope // number of steps used for default curve int minimum_steps = 0; - /* power for non-linear acceleration curves. - vs*(1-i^g)+ve*(i^g) where - vs = start speed, ve = end speed, - i = 0.0 for first entry and i = 1.0 for last entry in default table - */ + // power for non-linear acceleration curves. float g = 0; +}; - /* start speed, max end speed, step number */ - /* maximum speed (second field) is used to compute exposure as seen by motor */ - /* exposure=max speed/ slope dpi * base dpi */ - /* 5144 = max pixels at 600 dpi */ - /* 1288=(5144+8)*ydpi(=300)/base_dpi(=1200) , where 5152 is exposure */ - /* 6440=9660/(1932/1288) */ - // { 9560, 1912, 31, 0.8 }, +struct MotorSlope +{ + // initial speed in pixeltime per step + unsigned initial_speed_w = 0; + + // max speed in pixeltime per step + unsigned max_speed_w = 0; + + // acceleration in steps per pixeltime squared. + float acceleration = 0; + + unsigned get_table_step_shifted(unsigned step, StepType step_type) const; +}; + +struct MotorSlopeTable +{ + constexpr static unsigned SLOPE_TABLE_SIZE = 1024; + + std::vector table; + unsigned scan_steps = 0; + unsigned pixeltime_sum = 0; +}; + +MotorSlopeTable create_slope_table(const MotorSlope& slope, unsigned target_speed_w, + StepType step_type, unsigned steps_alignment, + unsigned min_size); + +class Genesys_Motor_Slope +{ +public: + enum SlopeType : unsigned { + LEGACY, + PHYSICAL + }; + + Genesys_Motor_Slope(const MotorSlopeLegacy& slope) : legacy_slope_{slope}, type_{LEGACY} {} + Genesys_Motor_Slope(const MotorSlope& slope) : slope_{slope}, type_{PHYSICAL} {} + Genesys_Motor_Slope(const Genesys_Motor_Slope&) = default; + Genesys_Motor_Slope& operator=(const Genesys_Motor_Slope&) = default; + + SlopeType type() const { return type_; } + + const MotorSlopeLegacy& legacy() const + { + if (type_ != LEGACY) + throw SaneException("Unexpected slope type"); + return legacy_slope_; + } + + const MotorSlope& physical() const + { + if (type_ != PHYSICAL) + throw SaneException("Unexpected slope type"); + return slope_; + } + +private: + MotorSlopeLegacy legacy_slope_; + MotorSlope slope_; + SlopeType type_; }; std::ostream& operator<<(std::ostream& out, const Genesys_Motor_Slope& slope); @@ -97,10 +202,26 @@ struct Genesys_Motor int base_ydpi = 0; // maximum resolution in y-direction. Unit: 1/inch int optical_ydpi = 0; - // maximum step type. 0-2 - int max_step_type = 0; // slopes to derive individual slopes from std::vector slopes; + + Genesys_Motor_Slope& get_slope(StepType step_type) + { + return slopes[static_cast(step_type)]; + } + + const Genesys_Motor_Slope& get_slope(StepType step_type) const + { + return slopes[static_cast(step_type)]; + } + + StepType max_step_type() const + { + if (slopes.empty()) { + throw std::runtime_error("Slopes table is empty"); + } + return static_cast(slopes.size() - 1); + } }; std::ostream& operator<<(std::ostream& out, const Genesys_Motor& motor); diff --git a/backend/genesys/scanner_interface.h b/backend/genesys/scanner_interface.h index b0540301e..03c713249 100644 --- a/backend/genesys/scanner_interface.h +++ b/backend/genesys/scanner_interface.h @@ -48,6 +48,7 @@ #include #include #include +#include namespace genesys { @@ -99,6 +100,8 @@ public: virtual void record_progress_message(const char* msg) = 0; + virtual void record_slope_table(unsigned table_nr, const std::vector& steps) = 0; + virtual void record_key_value(const std::string& key, const std::string& value) = 0; virtual void test_checkpoint(const std::string& name) = 0; diff --git a/backend/genesys/scanner_interface_usb.cpp b/backend/genesys/scanner_interface_usb.cpp index 6e9c51b5c..d4d83dd99 100644 --- a/backend/genesys/scanner_interface_usb.cpp +++ b/backend/genesys/scanner_interface_usb.cpp @@ -494,6 +494,13 @@ void ScannerInterfaceUsb::record_progress_message(const char* msg) sanei_usb_testing_record_message(msg); } +void ScannerInterfaceUsb::record_slope_table(unsigned table_nr, + const std::vector& steps) +{ + (void) table_nr; + (void) steps; +} + void ScannerInterfaceUsb::record_key_value(const std::string& key, const std::string& value) { (void) key; diff --git a/backend/genesys/scanner_interface_usb.h b/backend/genesys/scanner_interface_usb.h index 3cfd303f2..06b51ffb0 100644 --- a/backend/genesys/scanner_interface_usb.h +++ b/backend/genesys/scanner_interface_usb.h @@ -82,6 +82,8 @@ public: void record_progress_message(const char* msg) override; + void record_slope_table(unsigned table_nr, const std::vector& steps) override; + void record_key_value(const std::string& key, const std::string& value) override; void test_checkpoint(const std::string& name) override; diff --git a/backend/genesys/settings.cpp b/backend/genesys/settings.cpp index 7e52f28b2..41c66de78 100644 --- a/backend/genesys/settings.cpp +++ b/backend/genesys/settings.cpp @@ -82,7 +82,7 @@ std::ostream& operator<<(std::ostream& out, const SetupParams& params) << " startx: " << params.startx << " starty: " << params.starty << '\n' << " scan_mode: " << params.scan_mode << '\n' << " color_filter: " << params.color_filter << '\n' - << " flags: 0x" << std::hex << params.flags << std::dec << '\n' + << " flags: " << params.flags << '\n' << "}"; return out; } diff --git a/backend/genesys/settings.h b/backend/genesys/settings.h index 1cb83e60c..a697e604a 100644 --- a/backend/genesys/settings.h +++ b/backend/genesys/settings.h @@ -144,7 +144,7 @@ struct SetupParams { ColorFilter color_filter = static_cast(NOT_SET); - unsigned flags = NOT_SET; + ScanFlag flags; unsigned get_requested_pixels() const { @@ -160,8 +160,7 @@ struct SetupParams { pixels == NOT_SET || lines == NOT_SET ||depth == NOT_SET || channels == NOT_SET || scan_method == static_cast(NOT_SET) || scan_mode == static_cast(NOT_SET) || - color_filter == static_cast(NOT_SET) || - flags == NOT_SET) + color_filter == static_cast(NOT_SET)) { throw std::runtime_error("SetupParams are not valid"); } diff --git a/backend/genesys/static_init.cpp b/backend/genesys/static_init.cpp new file mode 100644 index 000000000..859a7059e --- /dev/null +++ b/backend/genesys/static_init.cpp @@ -0,0 +1,68 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#include "static_init.h" +#include + +namespace genesys { + +static std::unique_ptr>> s_functions_run_at_backend_exit; + +void add_function_to_run_at_backend_exit(const std::function& function) +{ + if (!s_functions_run_at_backend_exit) + s_functions_run_at_backend_exit.reset(new std::vector>()); + s_functions_run_at_backend_exit->push_back(std::move(function)); +} + +void run_functions_at_backend_exit() +{ + for (auto it = s_functions_run_at_backend_exit->rbegin(); + it != s_functions_run_at_backend_exit->rend(); ++it) + { + (*it)(); + } + s_functions_run_at_backend_exit.reset(); +} + +} // namespace genesys diff --git a/backend/genesys/static_init.h b/backend/genesys/static_init.h new file mode 100644 index 000000000..3ffa62c74 --- /dev/null +++ b/backend/genesys/static_init.h @@ -0,0 +1,88 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_STATIC_INIT_H +#define BACKEND_GENESYS_STATIC_INIT_H + +#include +#include + +namespace genesys { + +void add_function_to_run_at_backend_exit(const std::function& function); + +// calls functions added via add_function_to_run_at_backend_exit() in reverse order of being +// added. +void run_functions_at_backend_exit(); + +template +class StaticInit { +public: + StaticInit() = default; + StaticInit(const StaticInit&) = delete; + StaticInit& operator=(const StaticInit&) = delete; + + template + void init(Args&& ... args) + { + ptr_ = std::unique_ptr(new T(std::forward(args)...)); + add_function_to_run_at_backend_exit([this](){ deinit(); }); + } + + void deinit() + { + ptr_.reset(); + } + + const T* operator->() const { return ptr_.get(); } + T* operator->() { return ptr_.get(); } + const T& operator*() const { return *ptr_.get(); } + T& operator*() { return *ptr_.get(); } + +private: + std::unique_ptr ptr_; +}; + +} // namespace genesys + +#endif // BACKEND_GENESYS_STATIC_INIT_H diff --git a/backend/genesys/tables_motor.cpp b/backend/genesys/tables_motor.cpp index c91ac9e31..3c10f2758 100644 --- a/backend/genesys/tables_motor.cpp +++ b/backend/genesys/tables_motor.cpp @@ -53,22 +53,21 @@ void genesys_init_motor_tables() { s_motors.init(); - Genesys_Motor_Slope slope; + MotorSlopeLegacy slope; Genesys_Motor motor; motor.id = MotorId::UMAX; motor.base_ydpi = 1200; motor.optical_ydpi = 2400; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 11000; slope.maximum_speed = 3000; slope.minimum_steps = 128; slope.g = 1.0; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 11000; slope.maximum_speed = 3000; slope.minimum_steps = 128; @@ -82,16 +81,15 @@ void genesys_init_motor_tables() motor.id = MotorId::MD_5345; // MD5345/6228/6471 motor.base_ydpi = 1200; motor.optical_ydpi = 2400; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 2000; slope.maximum_speed = 1375; slope.minimum_steps = 128; slope.g = 0.5; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 2000; slope.maximum_speed = 1375; slope.minimum_steps = 128; @@ -105,16 +103,15 @@ void genesys_init_motor_tables() motor.id = MotorId::ST24; motor.base_ydpi = 2400; motor.optical_ydpi = 2400; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 2289; slope.maximum_speed = 2100; slope.minimum_steps = 128; slope.g = 0.3f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 2289; slope.maximum_speed = 2100; slope.minimum_steps = 128; @@ -128,16 +125,15 @@ void genesys_init_motor_tables() motor.id = MotorId::HP3670; motor.base_ydpi = 1200; motor.optical_ydpi = 2400; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 11000; slope.maximum_speed = 3000; slope.minimum_steps = 128; slope.g = 0.25; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 11000; slope.maximum_speed = 3000; slope.minimum_steps = 128; @@ -151,9 +147,8 @@ void genesys_init_motor_tables() motor.id = MotorId::HP2400; motor.base_ydpi = 1200; motor.optical_ydpi = 1200; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 11000; slope.maximum_speed = 3000; @@ -161,7 +156,7 @@ void genesys_init_motor_tables() slope.g = 0.25; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 11000; slope.maximum_speed = 3000; slope.minimum_steps = 128; @@ -175,16 +170,15 @@ void genesys_init_motor_tables() motor.id = MotorId::HP2300; motor.base_ydpi = 600; motor.optical_ydpi = 1200; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3200; slope.maximum_speed = 1200; slope.minimum_steps = 128; slope.g = 0.5; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3200; slope.maximum_speed = 1200; slope.minimum_steps = 128; @@ -198,16 +192,15 @@ void genesys_init_motor_tables() motor.id = MotorId::CANON_LIDE_35; motor.base_ydpi = 1200; motor.optical_ydpi = 2400; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3500; slope.maximum_speed = 1300; slope.minimum_steps = 60; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3500; slope.maximum_speed = 1400; slope.minimum_steps = 60; @@ -221,16 +214,15 @@ void genesys_init_motor_tables() motor.id = MotorId::XP200; motor.base_ydpi = 600; motor.optical_ydpi = 600; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3500; slope.maximum_speed = 1300; slope.minimum_steps = 60; slope.g = 0.25; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3500; slope.maximum_speed = 1400; slope.minimum_steps = 60; @@ -244,9 +236,8 @@ void genesys_init_motor_tables() motor.id = MotorId::XP300; motor.base_ydpi = 300; motor.optical_ydpi = 600; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); // works best with GPIO10, GPIO14 off slope.maximum_start_speed = 3700; slope.maximum_speed = 3700; @@ -254,7 +245,7 @@ void genesys_init_motor_tables() slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 11000; slope.maximum_speed = 11000; slope.minimum_steps = 2; @@ -268,16 +259,15 @@ void genesys_init_motor_tables() motor.id = MotorId::DP665; motor.base_ydpi = 750; motor.optical_ydpi = 1500; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3000; slope.maximum_speed = 2500; slope.minimum_steps = 10; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 11000; slope.maximum_speed = 11000; slope.minimum_steps = 2; @@ -291,16 +281,15 @@ void genesys_init_motor_tables() motor.id = MotorId::ROADWARRIOR; motor.base_ydpi = 750; motor.optical_ydpi = 1500; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3000; slope.maximum_speed = 2600; slope.minimum_steps = 10; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 11000; slope.maximum_speed = 11000; slope.minimum_steps = 2; @@ -313,16 +302,15 @@ void genesys_init_motor_tables() motor.id = MotorId::DSMOBILE_600; motor.base_ydpi = 750; motor.optical_ydpi = 1500; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 6666; slope.maximum_speed = 3700; slope.minimum_steps = 8; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 6666; slope.maximum_speed = 3700; slope.minimum_steps = 8; @@ -336,23 +324,22 @@ void genesys_init_motor_tables() motor.id = MotorId::CANON_LIDE_100; motor.base_ydpi = 1200; motor.optical_ydpi = 6400; - motor.max_step_type = 2; - slope = Genesys_Motor_Slope(); // full step + slope = MotorSlopeLegacy(); // full step slope.maximum_start_speed = 3000; slope.maximum_speed = 1000; slope.minimum_steps = 127; slope.g = 0.50; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); // half step + slope = MotorSlopeLegacy(); // half step slope.maximum_start_speed = 3000; slope.maximum_speed = 1500; slope.minimum_steps = 127; slope.g = 0.50; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); // quarter step 0.75*2712 + slope = MotorSlopeLegacy(); // quarter step 0.75*2712 slope.maximum_start_speed = 3*2712; slope.maximum_speed = 3*2712; slope.minimum_steps = 16; @@ -366,23 +353,22 @@ void genesys_init_motor_tables() motor.id = MotorId::CANON_LIDE_200; motor.base_ydpi = 1200; motor.optical_ydpi = 6400; - motor.max_step_type = 2; - slope = Genesys_Motor_Slope(); // full step + slope = MotorSlopeLegacy(); // full step slope.maximum_start_speed = 3000; slope.maximum_speed = 1000; slope.minimum_steps = 127; slope.g = 0.50; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); // half step + slope = MotorSlopeLegacy(); // half step slope.maximum_start_speed = 3000; slope.maximum_speed = 1500; slope.minimum_steps = 127; slope.g = 0.50; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); // quarter step 0.75*2712 + slope = MotorSlopeLegacy(); // quarter step 0.75*2712 slope.maximum_start_speed = 3*2712; slope.maximum_speed = 3*2712; slope.minimum_steps = 16; @@ -396,23 +382,22 @@ void genesys_init_motor_tables() motor.id = MotorId::CANON_LIDE_700; motor.base_ydpi = 1200; motor.optical_ydpi = 6400; - motor.max_step_type = 2; - slope = Genesys_Motor_Slope(); // full step + slope = MotorSlopeLegacy(); // full step slope.maximum_start_speed = 3000; slope.maximum_speed = 1000; slope.minimum_steps = 127; slope.g = 0.50f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); // half step + slope = MotorSlopeLegacy(); // half step slope.maximum_start_speed = 3000; slope.maximum_speed = 1500; slope.minimum_steps = 127; slope.g = 0.50f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); // quarter step 0.75*2712 + slope = MotorSlopeLegacy(); // quarter step 0.75*2712 slope.maximum_start_speed = 3*2712; slope.maximum_speed = 3*2712; slope.minimum_steps = 16; @@ -426,23 +411,22 @@ void genesys_init_motor_tables() motor.id = MotorId::KVSS080; motor.base_ydpi = 1200; motor.optical_ydpi = 1200; - motor.max_step_type = 2; - slope = Genesys_Motor_Slope(); // max speed / dpi * base dpi => exposure + slope = MotorSlopeLegacy(); // max speed / dpi * base dpi => exposure slope.maximum_start_speed = 22222; slope.maximum_speed = 500; slope.minimum_steps = 246; slope.g = 0.5; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 22222; slope.maximum_speed = 500; slope.minimum_steps = 246; slope.g = 0.5; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 22222; slope.maximum_speed = 500; slope.minimum_steps = 246; @@ -456,23 +440,22 @@ void genesys_init_motor_tables() motor.id = MotorId::G4050; motor.base_ydpi = 2400; motor.optical_ydpi = 9600; - motor.max_step_type = 2; - slope = Genesys_Motor_Slope(); // full step + slope = MotorSlopeLegacy(); // full step slope.maximum_start_speed = 3961; slope.maximum_speed = 240; slope.minimum_steps = 246; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); // half step + slope = MotorSlopeLegacy(); // half step slope.maximum_start_speed = 3961; slope.maximum_speed = 240; slope.minimum_steps = 246; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); // quarter step + slope = MotorSlopeLegacy(); // quarter step slope.maximum_start_speed = 3961; slope.maximum_speed = 240; slope.minimum_steps = 246; @@ -487,21 +470,21 @@ void genesys_init_motor_tables() motor.base_ydpi = 2400; motor.optical_ydpi = 9600; - slope = Genesys_Motor_Slope(); // full step + slope = MotorSlopeLegacy(); // full step slope.maximum_start_speed = 3961; slope.maximum_speed = 240; slope.minimum_steps = 246; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); // half step + slope = MotorSlopeLegacy(); // half step slope.maximum_start_speed = 3961; slope.maximum_speed = 240; slope.minimum_steps = 246; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); // quarter step + slope = MotorSlopeLegacy(); // quarter step slope.maximum_start_speed = 3961; slope.maximum_speed = 240; slope.minimum_steps = 246; @@ -515,23 +498,22 @@ void genesys_init_motor_tables() motor.id = MotorId::CANON_8400F; motor.base_ydpi = 1600; motor.optical_ydpi = 6400; - motor.max_step_type = 2; - slope = Genesys_Motor_Slope(); // full step + slope = MotorSlopeLegacy(); // full step slope.maximum_start_speed = 3961; slope.maximum_speed = 240; slope.minimum_steps = 246; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); // half step + slope = MotorSlopeLegacy(); // half step slope.maximum_start_speed = 3961; slope.maximum_speed = 240; slope.minimum_steps = 246; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); // quarter step + slope = MotorSlopeLegacy(); // quarter step slope.maximum_start_speed = 3961; slope.maximum_speed = 240; slope.minimum_steps = 246; @@ -545,23 +527,22 @@ void genesys_init_motor_tables() motor.id = MotorId::CANON_8600F; motor.base_ydpi = 2400; motor.optical_ydpi = 9600; - motor.max_step_type = 2; - slope = Genesys_Motor_Slope(); // full step + slope = MotorSlopeLegacy(); // full step slope.maximum_start_speed = 3961; slope.maximum_speed = 240; slope.minimum_steps = 246; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); // half step + slope = MotorSlopeLegacy(); // half step slope.maximum_start_speed = 3961; slope.maximum_speed = 240; slope.minimum_steps = 246; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); // quarter step + slope = MotorSlopeLegacy(); // quarter step slope.maximum_start_speed = 3961; slope.maximum_speed = 240; slope.minimum_steps = 246; @@ -575,9 +556,8 @@ void genesys_init_motor_tables() motor.id = MotorId::CANON_LIDE_110; motor.base_ydpi = 4800; motor.optical_ydpi = 9600; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); // full step + slope = MotorSlopeLegacy(); // full step slope.maximum_start_speed = 3000; slope.maximum_speed = 1000; slope.minimum_steps = 256; @@ -591,9 +571,8 @@ void genesys_init_motor_tables() motor.id = MotorId::CANON_LIDE_120; motor.base_ydpi = 4800; motor.optical_ydpi = 9600; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3000; slope.maximum_speed = 1000; slope.minimum_steps = 256; @@ -607,9 +586,8 @@ void genesys_init_motor_tables() motor.id = MotorId::CANON_LIDE_210; motor.base_ydpi = 4800; motor.optical_ydpi = 9600; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3000; slope.maximum_speed = 1000; slope.minimum_steps = 256; @@ -623,16 +601,15 @@ void genesys_init_motor_tables() motor.id = MotorId::PLUSTEK_OPTICPRO_3600; motor.base_ydpi = 1200; motor.optical_ydpi = 2400; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3500; slope.maximum_speed = 1300; slope.minimum_steps = 60; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3500; slope.maximum_speed = 3250; slope.minimum_steps = 60; @@ -646,7 +623,6 @@ void genesys_init_motor_tables() motor.id = MotorId::PLUSTEK_OPTICFILM_7200I; motor.base_ydpi = 3600; motor.optical_ydpi = 3600; - motor.max_step_type = 0; // only used on GL841 s_motors->push_back(std::move(motor)); @@ -654,7 +630,6 @@ void genesys_init_motor_tables() motor.id = MotorId::PLUSTEK_OPTICFILM_7300; motor.base_ydpi = 3600; motor.optical_ydpi = 3600; - motor.max_step_type = 0; s_motors->push_back(std::move(motor)); @@ -662,7 +637,6 @@ void genesys_init_motor_tables() motor.id = MotorId::PLUSTEK_OPTICFILM_7500I; motor.base_ydpi = 3600; motor.optical_ydpi = 3600; - motor.max_step_type = 0; s_motors->push_back(std::move(motor)); @@ -670,16 +644,15 @@ void genesys_init_motor_tables() motor.id = MotorId::IMG101; motor.base_ydpi = 600; motor.optical_ydpi = 1200; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3500; slope.maximum_speed = 1300; slope.minimum_steps = 60; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3500; slope.maximum_speed = 3250; slope.minimum_steps = 60; @@ -693,16 +666,15 @@ void genesys_init_motor_tables() motor.id = MotorId::PLUSTEK_OPTICBOOK_3800; motor.base_ydpi = 600; motor.optical_ydpi = 1200; - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3500; slope.maximum_speed = 1300; slope.minimum_steps = 60; slope.g = 0.8f; motor.slopes.push_back(slope); - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 3500; slope.maximum_speed = 3250; slope.minimum_steps = 60; @@ -716,9 +688,8 @@ void genesys_init_motor_tables() motor.id = MotorId::CANON_LIDE_80; motor.base_ydpi = 2400; motor.optical_ydpi = 4800; // 9600 - motor.max_step_type = 1; - slope = Genesys_Motor_Slope(); + slope = MotorSlopeLegacy(); slope.maximum_start_speed = 9560; slope.maximum_speed = 1912; slope.minimum_steps = 31; diff --git a/backend/genesys/tables_motor_profile.cpp b/backend/genesys/tables_motor_profile.cpp index c3b821f51..08a06e188 100644 --- a/backend/genesys/tables_motor_profile.cpp +++ b/backend/genesys/tables_motor_profile.cpp @@ -777,22 +777,103 @@ static std::uint32_t motor_speeds_plustek_7500i_2[] = { 7200 dpi: 31250, 11000, 11000, */ -Motor_Profile gl843_motor_profiles[] = { - { MotorId::KVSS080, 8000, StepType::HALF, kvss080 }, - { MotorId::G4050, 8016, StepType::HALF, g4050_fast }, - { MotorId::G4050, 15624, StepType::HALF, g4050_xpa }, - { MotorId::G4050, 42752, StepType::QUARTER, g4050_max }, - { MotorId::G4050, 56064, StepType::HALF, g4050_high }, - { MotorId::CANON_4400F, 11640, StepType::HALF, motor_speeds_cs4400f_1}, - { MotorId::CANON_8400F, 50000, StepType::QUARTER, cs8400f_fast }, - { MotorId::CANON_8600F, 0x59d8, StepType::QUARTER, motor_speeds_cs8600f }, // FIXME: if the exposure is lower then we'll select another motor - { MotorId::PLUSTEK_OPTICFILM_7200I, 0x19c8, StepType::HALF, motor_speeds_plustek_7200i_1}, - { MotorId::PLUSTEK_OPTICFILM_7200I, 0x2538, StepType::HALF, motor_speeds_plustek_7200i_2}, - { MotorId::PLUSTEK_OPTICFILM_7300, 0x2f44, StepType::QUARTER, motor_speeds_plustek_7300_1}, - { MotorId::PLUSTEK_OPTICFILM_7500I, 0x2f44, StepType::QUARTER, motor_speeds_plustek_7500i_1}, - { MotorId::PLUSTEK_OPTICFILM_7500I, 0x2af8, StepType::QUARTER, motor_speeds_plustek_7500i_2}, - { MotorId::UNKNOWN, 0, StepType::FULL, nullptr }, -}; +StaticInit> gl843_motor_profiles; + +void genesys_init_motor_profile_tables_gl843() +{ + gl843_motor_profiles.init(); + + auto profile = Motor_Profile(); + profile.motor_id = MotorId::KVSS080; + profile.exposure = 8000; + profile.step_type = StepType::HALF; + profile.table = kvss080; + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::G4050; + profile.exposure = 8016; + profile.step_type = StepType::HALF; + profile.table = g4050_fast; + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::G4050; + profile.exposure = 15624; + profile.step_type = StepType::HALF; + profile.table = g4050_xpa; + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::G4050; + profile.exposure = 42752; + profile.step_type = StepType::QUARTER; + profile.table = g4050_max; + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::G4050; + profile.exposure = 56064; + profile.step_type = StepType::HALF; + profile.table = g4050_high; + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_4400F; + profile.exposure = 11640; + profile.step_type = StepType::HALF; + profile.table = motor_speeds_cs4400f_1; + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_8400F; + profile.exposure = 50000; + profile.step_type = StepType::QUARTER; + profile.table = cs8400f_fast; + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_8600F; + profile.exposure = 0x59d8; + profile.step_type = StepType::QUARTER; + profile.table = motor_speeds_cs8600f; // FIXME: if the exposure is lower then we'll select another motor + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::PLUSTEK_OPTICFILM_7200I; + profile.exposure = 0x19c8; + profile.step_type = StepType::HALF; + profile.table = motor_speeds_plustek_7200i_1; + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::PLUSTEK_OPTICFILM_7200I; + profile.exposure = 0x2538; + profile.step_type = StepType::HALF; + profile.table = motor_speeds_plustek_7200i_2; + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::PLUSTEK_OPTICFILM_7300; + profile.exposure = 0x2f44; + profile.step_type = StepType::QUARTER; + profile.table = motor_speeds_plustek_7300_1; + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::PLUSTEK_OPTICFILM_7500I; + profile.exposure = 0x2f44; + profile.step_type = StepType::QUARTER; + profile.table = motor_speeds_plustek_7500i_1; + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::PLUSTEK_OPTICFILM_7500I; + profile.exposure = 0x2af8; + profile.step_type = StepType::QUARTER; + profile.table = motor_speeds_plustek_7500i_2; + gl843_motor_profiles->push_back(profile); +} /* base motor slopes in full step unit */ /* target=((exposure * dpi) / base_dpi)>>step_type; */ @@ -902,15 +983,26 @@ static uint32_t img101_high[] = { 0 }; -/** - * database of motor profiles - */ +StaticInit> gl846_motor_profiles; -Motor_Profile gl846_motor_profiles[] = { - { MotorId::IMG101, 11000, StepType::HALF, img101_high}, - { MotorId::PLUSTEK_OPTICBOOK_3800, 11000, StepType::HALF, img101_high}, - { MotorId::UNKNOWN, 0, StepType::FULL, nullptr }, -}; +void genesys_init_motor_profile_tables_gl846() +{ + gl846_motor_profiles.init(); + + auto profile = Motor_Profile(); + profile.motor_id = MotorId::IMG101; + profile.exposure = 11000; + profile.step_type = StepType::HALF; + profile.table = img101_high; + gl846_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::PLUSTEK_OPTICBOOK_3800; + profile.exposure = 11000; + profile.step_type = StepType::HALF; + profile.table = img101_high; + gl846_motor_profiles->push_back(profile); +} /* base motor sopes in full step unit */ /* target=((exposure * dpi) / base_dpi)>>step_type; */ @@ -1048,39 +1140,128 @@ static uint32_t lide700_high[] = { 15864, 15864, 15864, 15864, 15864, 15864 }; -/* 5190 trop - * 5186 pas assez - */ -/* -static uint32_t lide200_max[] = { 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 2219,2212,2205,2198,2190,2183,2176,2168,2161,2154,2146,2139,2132,2125,2117,2110,2103,2095,2088,2081,2073,2066,2059,2052,2044,2037,2030,2022,2015,2008,2001,1993,1986,1979,1971,1964,1957,1949,1942,1935,1928,1920,1913,1906,1898,1891,1884,1876,1869,1862,1855,1847,1840,1833,1825,1818,1811,1803,1796,1789,1782,1774,1767,1760,1752,1745,1738,1731,1723,1716,1709,1701,1694,1687,1679,1672,1665,1658,1650,1643,1636,1628,1621,1614,1606,1599,1592,1585,1577,1570,1563,1555,1548,1541,1533,1526,1519,1512,1504,1497,1490,1482,1475,1468,1461,1453,1446,1439,1431,1424,1417,1409,1402,1395,1388,1380,1373,1366,1358,1351,1344,1336,1329,1322,1315,1307,1300,1293,1285,1278,1271,1263,1256,1249,1242,1234,1227,1220,1212,1205,1198,1191,1183,1176,1169,1161,1154,1147,1139,1132,1125,1118,1110,1103,1096,1088,1081,1074,1066,1059,1052,1045,1037,1030,1023,1015,1008,1001,993,986,979,972,964,957,950,942,935,928,921,913,906,899,891,884,877,869,862,855,848,840,833,826,818,811,804,796,789,782,775,767,760,753,745,738,731,723,716,709,702,694,687,680,672,665,658,651,643,636,629,621,614,607,599,592,585,578,570,563,556,534,534, 0}; -*/ - /** * database of motor profiles */ -Motor_Profile gl847_motor_profiles[] = { - { MotorId::CANON_LIDE_100, 2848, StepType::HALF , lide200_base }, - { MotorId::CANON_LIDE_100, 1424, StepType::HALF , lide200_base }, - { MotorId::CANON_LIDE_100, 1432, StepType::HALF , lide200_base }, - { MotorId::CANON_LIDE_100, 2712, StepType::QUARTER, lide200_medium }, - { MotorId::CANON_LIDE_100, 5280, StepType::EIGHTH , lide200_high }, +StaticInit> gl847_motor_profiles; - { MotorId::CANON_LIDE_200, 2848, StepType::HALF , lide200_base }, - { MotorId::CANON_LIDE_200, 1424, StepType::HALF , lide200_base }, - { MotorId::CANON_LIDE_200, 1432, StepType::HALF , lide200_base }, - { MotorId::CANON_LIDE_200, 2712, StepType::QUARTER, lide200_medium }, - { MotorId::CANON_LIDE_200, 5280, StepType::EIGHTH , lide200_high }, - { MotorId::CANON_LIDE_200, 10416, StepType::EIGHTH , lide200_high }, +void genesys_init_motor_profile_tables_gl847() +{ + gl847_motor_profiles.init(); - { MotorId::CANON_LIDE_700, 2848, StepType::HALF , lide200_base }, - { MotorId::CANON_LIDE_700, 1424, StepType::HALF , lide200_base }, - { MotorId::CANON_LIDE_700, 1504, StepType::HALF , lide200_base }, - { MotorId::CANON_LIDE_700, 2696, StepType::HALF , lide700_medium }, /* 2696 , 2838 */ - { MotorId::CANON_LIDE_700, 10576, StepType::EIGHTH, lide700_high }, + auto profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_100; + profile.exposure = 2848; + profile.step_type = StepType::HALF; + profile.table = lide200_base; + gl847_motor_profiles->push_back(profile); - { MotorId::UNKNOWN, 0, StepType::FULL, nullptr }, -}; + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_100; + profile.exposure = 1424; + profile.step_type = StepType::HALF; + profile.table = lide200_base; + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_100; + profile.exposure = 1432; + profile.step_type = StepType::HALF; + profile.table = lide200_base; + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_100; + profile.exposure = 2712; + profile.step_type = StepType::QUARTER; + profile.table = lide200_medium; + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_100; + profile.exposure = 5280; + profile.step_type = StepType::EIGHTH; + profile.table = lide200_high; + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_200; + profile.exposure = 2848; + profile.step_type = StepType::HALF; + profile.table = lide200_base; + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_200; + profile.exposure = 1424; + profile.step_type = StepType::HALF; + profile.table = lide200_base; + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_200; + profile.exposure = 1432; + profile.step_type = StepType::HALF; + profile.table = lide200_base; + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_200; + profile.exposure = 2712; + profile.step_type = StepType::QUARTER; + profile.table = lide200_medium; + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_200; + profile.exposure = 5280; + profile.step_type = StepType::EIGHTH; + profile.table = lide200_high; + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_200; + profile.exposure = 10416; + profile.step_type = StepType::EIGHTH; + profile.table = lide200_high; + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_700; + profile.exposure = 2848; + profile.step_type = StepType::HALF; + profile.table = lide200_base; + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_700; + profile.exposure = 1424; + profile.step_type = StepType::HALF; + profile.table = lide200_base; + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_700; + profile.exposure = 1504; + profile.step_type = StepType::HALF; + profile.table = lide200_base; + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_700; + profile.exposure = 2696; + profile.step_type = StepType::HALF; + profile.table = lide700_medium; + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_700; + profile.exposure = 10576; + profile.step_type = StepType::EIGHTH; + profile.table = lide700_high; + gl847_motor_profiles->push_back(profile); +} static uint32_t lide210_fast[] = { 62496, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2051, @@ -1194,24 +1375,104 @@ static uint32_t lide110_max[] = { 62496, 31296, 10432, 0 }; static uint32_t lide120_max[] = { 62592, 62592, 41728, 31296, 10432, 0 }; static uint32_t lide210_max[] = { 62496, 31296, 20864, 10432, 0 }; -// NEXT LPERIOD=PREVIOUS*2-192 -Motor_Profile gl124_motor_profiles[] = { - { MotorId::CANON_LIDE_110, 2768, StepType::FULL, lide210_fast }, - { MotorId::CANON_LIDE_110, 5360, StepType::HALF, lide110_ok }, - { MotorId::CANON_LIDE_110, 10528, StepType::HALF, lide110_slow }, - { MotorId::CANON_LIDE_110, 20864, StepType::QUARTER, lide110_max }, +StaticInit> gl124_motor_profiles; - { MotorId::CANON_LIDE_120, 4608, StepType::FULL, lide120_fast }, - { MotorId::CANON_LIDE_120, 5360, StepType::HALF, lide120_ok }, - { MotorId::CANON_LIDE_120, 10528, StepType::QUARTER, lide120_slow }, - { MotorId::CANON_LIDE_120, 20864, StepType::QUARTER, lide120_max }, +void genesys_init_motor_profile_tables_gl124() +{ + gl124_motor_profiles.init(); - { MotorId::CANON_LIDE_210, 2768, StepType::FULL, lide210_fast }, - { MotorId::CANON_LIDE_210, 5360, StepType::HALF, lide110_ok }, - { MotorId::CANON_LIDE_210, 10528, StepType::HALF, lide110_slow }, - { MotorId::CANON_LIDE_210, 20864, StepType::QUARTER, lide210_max }, + // NEXT LPERIOD=PREVIOUS*2-192 + Motor_Profile profile; + profile.motor_id = MotorId::CANON_LIDE_110; + profile.exposure = 2768; + profile.step_type = StepType::FULL; + profile.table = lide210_fast; + gl124_motor_profiles->push_back(profile); - { MotorId::UNKNOWN, 0, StepType::FULL, nullptr }, -}; + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_110; + profile.exposure = 5360; + profile.step_type = StepType::HALF; + profile.table = lide110_ok; + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_110; + profile.exposure = 10528; + profile.step_type = StepType::HALF; + profile.table = lide110_slow; + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_110; + profile.exposure = 20864; + profile.step_type = StepType::QUARTER; + profile.table = lide110_max; + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_120; + profile.exposure = 4608; + profile.step_type = StepType::FULL; + profile.table = lide120_fast; + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_120; + profile.exposure = 5360; + profile.step_type = StepType::HALF; + profile.table = lide120_ok; + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_120; + profile.exposure = 10528; + profile.step_type = StepType::QUARTER; + profile.table = lide120_slow; + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_120; + profile.exposure = 20864; + profile.step_type = StepType::QUARTER; + profile.table = lide120_max; + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_210; + profile.exposure = 2768; + profile.step_type = StepType::FULL; + profile.table = lide210_fast; + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_210; + profile.exposure = 5360; + profile.step_type = StepType::HALF; + profile.table = lide110_ok; + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_210; + profile.exposure = 10528; + profile.step_type = StepType::HALF; + profile.table = lide110_slow; + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_210; + profile.exposure = 20864; + profile.step_type = StepType::QUARTER; + profile.table = lide210_max; + gl124_motor_profiles->push_back(profile); +} + +void genesys_init_motor_profile_tables() +{ + genesys_init_motor_profile_tables_gl843(); + genesys_init_motor_profile_tables_gl846(); + genesys_init_motor_profile_tables_gl847(); + genesys_init_motor_profile_tables_gl124(); +} } // namespace genesys diff --git a/backend/genesys/test_scanner_interface.cpp b/backend/genesys/test_scanner_interface.cpp index b594e6428..12f726f32 100644 --- a/backend/genesys/test_scanner_interface.cpp +++ b/backend/genesys/test_scanner_interface.cpp @@ -183,6 +183,17 @@ void TestScannerInterface::sleep_us(unsigned microseconds) (void) microseconds; } +void TestScannerInterface::record_slope_table(unsigned table_nr, + const std::vector& steps) +{ + slope_tables_[table_nr] = steps; +} + +std::map>& TestScannerInterface::recorded_slope_tables() +{ + return slope_tables_; +} + void TestScannerInterface::record_progress_message(const char* msg) { last_progress_message_ = msg; diff --git a/backend/genesys/test_scanner_interface.h b/backend/genesys/test_scanner_interface.h index 709283565..acf0f6d4a 100644 --- a/backend/genesys/test_scanner_interface.h +++ b/backend/genesys/test_scanner_interface.h @@ -90,6 +90,10 @@ public: const std::string& last_progress_message() const; + void record_slope_table(unsigned table_nr, const std::vector& steps) override; + + std::map>& recorded_slope_tables(); + void record_key_value(const std::string& key, const std::string& value) override; std::map& recorded_key_values(); @@ -106,6 +110,9 @@ private: TestUsbDevice usb_dev_; TestCheckpointCallback checkpoint_callback_; + + std::map> slope_tables_; + std::string last_progress_message_; std::map key_values_; }; diff --git a/testsuite/backend/genesys/Makefile.am b/testsuite/backend/genesys/Makefile.am index 525310e19..818a523c6 100644 --- a/testsuite/backend/genesys/Makefile.am +++ b/testsuite/backend/genesys/Makefile.am @@ -24,6 +24,7 @@ genesys_unit_tests_SOURCES = tests.cpp tests.h \ tests_calibration.cpp \ tests_image.cpp \ tests_image_pipeline.cpp \ + tests_motor.cpp \ tests_row_buffer.cpp \ tests_utilities.cpp diff --git a/testsuite/backend/genesys/session_config_test.cpp b/testsuite/backend/genesys/session_config_test.cpp index d1631c4eb..42c3066df 100644 --- a/testsuite/backend/genesys/session_config_test.cpp +++ b/testsuite/backend/genesys/session_config_test.cpp @@ -212,6 +212,18 @@ void build_checkpoint(const genesys::Genesys_Device& dev, << "iface.cached_fe_regs: " << genesys::format_indent_braced_list(4, iface.cached_fe_regs()) << "\n\n" << "iface.last_progress_message: " << iface.last_progress_message() << "\n\n"; + out << "iface.slope_tables: {\n"; + for (const auto& kv : iface.recorded_slope_tables()) { + out << " " << kv.first << ": {"; + for (unsigned i = 0; i < kv.second.size(); ++i) { + if (i % 10 == 0) { + out << "\n "; + } + out << ' ' << kv.second[i]; + } + out << "\n }\n"; + } + out << "}\n"; if (iface.recorded_key_values().empty()) { out << "iface.recorded_key_values: []\n"; } else { @@ -221,6 +233,7 @@ void build_checkpoint(const genesys::Genesys_Device& dev, } out << "}\n"; } + iface.recorded_key_values().clear(); out << "\n"; } diff --git a/testsuite/backend/genesys/tests.cpp b/testsuite/backend/genesys/tests.cpp index 4c172ddea..5fe00844d 100644 --- a/testsuite/backend/genesys/tests.cpp +++ b/testsuite/backend/genesys/tests.cpp @@ -30,6 +30,7 @@ int main() genesys::test_calibration_parsing(); genesys::test_image(); genesys::test_image_pipeline(); + genesys::test_motor(); genesys::test_row_buffer(); genesys::test_utilities(); return finish_tests(); diff --git a/testsuite/backend/genesys/tests.h b/testsuite/backend/genesys/tests.h index 3459c2b02..c48c58606 100644 --- a/testsuite/backend/genesys/tests.h +++ b/testsuite/backend/genesys/tests.h @@ -28,6 +28,7 @@ namespace genesys { void test_calibration_parsing(); void test_image(); void test_image_pipeline(); +void test_motor(); void test_row_buffer(); void test_utilities(); diff --git a/testsuite/backend/genesys/tests_motor.cpp b/testsuite/backend/genesys/tests_motor.cpp new file mode 100644 index 000000000..b52867b96 --- /dev/null +++ b/testsuite/backend/genesys/tests_motor.cpp @@ -0,0 +1,387 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "tests.h" +#include "minigtest.h" +#include "tests_printers.h" + +#include "../../../backend/genesys/low.h" +#include "../../../backend/genesys/enums.h" + +namespace genesys { + +void test_create_slope_table3() +{ + MotorSlopeLegacy slope; + + Genesys_Motor motor; + motor.id = MotorId::CANON_LIDE_200; + motor.base_ydpi = 1200; + motor.optical_ydpi = 6400; + + slope = MotorSlopeLegacy(); // full step + slope.maximum_start_speed = 10000; + slope.maximum_speed = 1000; + slope.minimum_steps = 20; + slope.g = 0.80; + motor.slopes.push_back(slope); + + slope = MotorSlopeLegacy(); // half step + slope.maximum_start_speed = 10000; + slope.maximum_speed = 1000; + slope.minimum_steps = 20; + slope.g = 0.80; + motor.slopes.push_back(slope); + + slope = MotorSlopeLegacy(); // quarter step 0.75*2712 + slope.maximum_start_speed = 10000; + slope.maximum_speed = 1000; + slope.minimum_steps = 16; + slope.g = 0.80f; + motor.slopes.push_back(slope); + + unsigned used_steps = 0; + unsigned final_exposure = 0; + unsigned sum_time = 0; + std::vector slope_table; + + sum_time = sanei_genesys_create_slope_table3(motor, slope_table, 20, 20, StepType::FULL, + 10000, motor.base_ydpi, &used_steps, + &final_exposure); + + ASSERT_EQ(sum_time, 10000u); + ASSERT_EQ(used_steps, 1u); + ASSERT_EQ(final_exposure, 10000u); + + std::vector expected_steps = { + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + }; + + ASSERT_EQ(slope_table, expected_steps); + + sum_time = sanei_genesys_create_slope_table3(motor, slope_table, 20, 20, StepType::FULL, + 2000, motor.base_ydpi, &used_steps, + &final_exposure); + + ASSERT_EQ(sum_time, 98183u); + ASSERT_EQ(used_steps, 18u); + ASSERT_EQ(final_exposure, 1766u); + + expected_steps = { + 10000, 9146, 8513, 7944, 7412, 6906, 6421, 5951, 5494, 5049, + 4614, 4187, 3768, 3356, 2950, 2550, 2156, 1766, 1766, 1766, + }; + + ASSERT_EQ(slope_table, expected_steps); + + sum_time = sanei_genesys_create_slope_table3(motor, slope_table, 20, 20, StepType::HALF, + 10000, motor.base_ydpi, &used_steps, + &final_exposure); + + ASSERT_EQ(sum_time, 5000u); + ASSERT_EQ(used_steps, 1u); + ASSERT_EQ(final_exposure, 5000u); + + expected_steps = { + 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, + 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, + }; + + ASSERT_EQ(slope_table, expected_steps); + + sum_time = sanei_genesys_create_slope_table3(motor, slope_table, 20, 20, StepType::HALF, + 2000, motor.base_ydpi, &used_steps, + &final_exposure); + + ASSERT_EQ(sum_time, 72131u); + ASSERT_EQ(used_steps, 20u); + ASSERT_EQ(final_exposure, 2575u); + + expected_steps = { + 5000, 4759, 4581, 4421, 4272, 4129, 3993, 3861, 3732, 3607, + 3485, 3365, 3247, 3131, 3017, 2904, 2793, 2684, 2575, 2575, + }; + + ASSERT_EQ(slope_table, expected_steps); + + sum_time = sanei_genesys_create_slope_table3(motor, slope_table, 20, 20, StepType::QUARTER, + 10000, motor.base_ydpi, &used_steps, + &final_exposure); + + ASSERT_EQ(sum_time, 2500u); + ASSERT_EQ(used_steps, 1u); + ASSERT_EQ(final_exposure, 2500u); + + expected_steps = { + 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, + 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, + }; + + ASSERT_EQ(slope_table, expected_steps); + + sum_time = sanei_genesys_create_slope_table3(motor, slope_table, 20, 20, StepType::QUARTER, + 2000, motor.base_ydpi, &used_steps, + &final_exposure); + + ASSERT_EQ(sum_time, 40503u); + ASSERT_EQ(used_steps, 20u); + ASSERT_EQ(final_exposure, 1674u); + + expected_steps = { + 2500, 2418, 2357, 2303, 2252, 2203, 2157, 2112, 2068, 2025, + 1983, 1943, 1902, 1863, 1824, 1786, 1748, 1711, 1674, 1674, + }; + + ASSERT_EQ(slope_table, expected_steps); +} + +void test_create_slope_table_small_full_step() +{ + // created approximately from LIDE 110 slow table: { 62464, 7896, 2632, 0 } + MotorSlope slope; + slope.initial_speed_w = 62464; + slope.max_speed_w = 2632; + slope.acceleration = 1.2e-8; + + auto table = create_slope_table(slope, 5000, StepType::FULL, 4, 8); + + std::vector expected_table = { + 62464, 62464, 6420, 5000 + }; + expected_table.resize(table.SLOPE_TABLE_SIZE, 5000); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.scan_steps, 8u); + ASSERT_EQ(table.pixeltime_sum, 156348u); + + + table = create_slope_table(slope, 3000, StepType::FULL, 4, 8); + + expected_table = { + 62464, 62464, 6420, 4552, 3720, 3223, 3000 + }; + expected_table.resize(table.SLOPE_TABLE_SIZE, 3000); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.scan_steps, 8u); + ASSERT_EQ(table.pixeltime_sum, 148843u); +} + +void test_create_slope_table_small_full_step_target_speed_too_high() +{ + // created approximately from LIDE 110 slow table: { 62464, 7896, 2632, 0 } + MotorSlope slope; + slope.initial_speed_w = 62464; + slope.max_speed_w = 2632; + slope.acceleration = 1.2e-8; + + auto table = create_slope_table(slope, 2000, StepType::FULL, 4, 8); + + std::vector expected_table = { + 62464, 62464, 6420, 4552, 3720, 3223, 2883, 2632 + }; + expected_table.resize(table.SLOPE_TABLE_SIZE, 2632); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.scan_steps, 8u); + ASSERT_EQ(table.pixeltime_sum, 148358u); +} + +void test_create_slope_table_small_half_step() +{ + // created approximately from LIDE 110 slow table: { 62464, 7896, 2632, 0 } + MotorSlope slope; + slope.initial_speed_w = 62464; + slope.max_speed_w = 2632; + slope.acceleration = 1.2e-8; + + auto table = create_slope_table(slope, 5000, StepType::HALF, 4, 8); + + std::vector expected_table = { + 31232, 31232, 3210, 2500 + }; + expected_table.resize(table.SLOPE_TABLE_SIZE, 2500); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.scan_steps, 8u); + ASSERT_EQ(table.pixeltime_sum, 78174u); + + + table = create_slope_table(slope, 3000, StepType::HALF, 4, 8); + + expected_table = { + 31232, 31232, 3210, 2276, 1860, 1611, 1500 + }; + expected_table.resize(table.SLOPE_TABLE_SIZE, 1500); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.scan_steps, 8u); + ASSERT_EQ(table.pixeltime_sum, 74421u); +} + +void test_create_slope_table_large_full_step() +{ + /* created approximately from Canon 8600F table: + 54612, 54612, 34604, 26280, 21708, 18688, 16564, 14936, 13652, 12616, + 11768, 11024, 10400, 9872, 9392, 8960, 8584, 8240, 7940, 7648, + 7404, 7160, 6948, 6732, 6544, 6376, 6208, 6056, 5912, 5776, + 5644, 5520, 5408, 5292, 5192, 5092, 5000, 4908, 4820, 4736, + 4660, 4580, 4508, 4440, 4368, 4304, 4240, 4184, 4124, 4068, + 4012, 3960, 3908, 3860, 3808, 3764, 3720, 3676, 3636, 3592, + 3552, 3516, 3476, 3440, 3400, 3368, 3332, 3300, 3268, 3236, + 3204, 3176, 3148, 3116, 3088, 3060, 3036, 3008, 2984, 2956, + 2932, 2908, 2884, 2860, 2836, 2816, 2796, 2772, 2752, 2732, + 2708, 2692, 2672, 2652, 2632, 2616, 2596, 2576, 2560, 2544, + 2528, 2508, 2492, 2476, 2460, 2444, 2432, 2416, 2400, 2384, + 2372, 2356, 2344, 2328, 2316, 2304, 2288, 2276, 2260, 2252, + 2236, 2224, 2212, 2200, 2188, 2176, 2164, 2156, 2144, 2132, + 2120, 2108, 2100, 2088, 2080, 2068, 2056, 2048, 2036, 2028, + 2020, 2008, 2000, 1988, 1980, 1972, 1964, 1952, 1944, 1936, + 1928, 1920, 1912, 1900, 1892, 1884, 1876, 1868, 1860, 1856, + 1848, 1840, 1832, 1824, 1816, 1808, 1800, 1796, 1788, 1780, + 1772, 1764, 1760, 1752, 1744, 1740, 1732, 1724, 1720, 1712, + 1708, 1700, 1692, 1688, 1680, 1676, 1668, 1664, 1656, 1652, + 1644, 1640, 1636, 1628, 1624, 1616, 1612, 1608, 1600, 1596, + 1592, 1584, 1580, 1576, 1568, 1564, 1560, 1556, 1548, 1544, + 1540, 1536, 1528, 1524, 1520, 1516, 1512, 1508, 1500, + */ + MotorSlope slope; + slope.initial_speed_w = 54612; + slope.max_speed_w = 1500; + slope.acceleration = 1.013948e-9; + + auto table = create_slope_table(slope, 3000, StepType::FULL, 4, 8); + + std::vector expected_table = { + 54612, 54612, 20570, 15090, 12481, 10880, 9770, 8943, 8295, 7771, + 7335, 6964, 6645, 6366, 6120, 5900, 5702, 5523, 5359, 5210, + 5072, 4945, 4826, 4716, 4613, 4517, 4426, 4341, 4260, 4184, + 4111, 4043, 3977, 3915, 3855, 3799, 3744, 3692, 3642, 3594, + 3548, 3503, 3461, 3419, 3379, 3341, 3304, 3268, 3233, 3199, + 3166, 3135, 3104, 3074, 3045, 3017, 3000, + }; + expected_table.resize(table.SLOPE_TABLE_SIZE, 3000); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.scan_steps, 60u); + ASSERT_EQ(table.pixeltime_sum, 412616u); + + + table = create_slope_table(slope, 1500, StepType::FULL, 4, 8); + + expected_table = { + 54612, 54612, 20570, 15090, 12481, 10880, 9770, 8943, 8295, 7771, + 7335, 6964, 6645, 6366, 6120, 5900, 5702, 5523, 5359, 5210, + 5072, 4945, 4826, 4716, 4613, 4517, 4426, 4341, 4260, 4184, + 4111, 4043, 3977, 3915, 3855, 3799, 3744, 3692, 3642, 3594, + 3548, 3503, 3461, 3419, 3379, 3341, 3304, 3268, 3233, 3199, + 3166, 3135, 3104, 3074, 3045, 3017, 2989, 2963, 2937, 2911, + 2886, 2862, 2839, 2816, 2794, 2772, 2750, 2729, 2709, 2689, + 2670, 2651, 2632, 2614, 2596, 2578, 2561, 2544, 2527, 2511, + 2495, 2480, 2464, 2449, 2435, 2420, 2406, 2392, 2378, 2364, + 2351, 2338, 2325, 2313, 2300, 2288, 2276, 2264, 2252, 2241, + 2229, 2218, 2207, 2196, 2186, 2175, 2165, 2155, 2145, 2135, + 2125, 2115, 2106, 2096, 2087, 2078, 2069, 2060, 2051, 2042, + 2034, 2025, 2017, 2009, 2000, 1992, 1984, 1977, 1969, 1961, + 1953, 1946, 1938, 1931, 1924, 1917, 1910, 1903, 1896, 1889, + 1882, 1875, 1869, 1862, 1855, 1849, 1843, 1836, 1830, 1824, + 1818, 1812, 1806, 1800, 1794, 1788, 1782, 1776, 1771, 1765, + 1760, 1754, 1749, 1743, 1738, 1733, 1727, 1722, 1717, 1712, + 1707, 1702, 1697, 1692, 1687, 1682, 1677, 1673, 1668, 1663, + 1659, 1654, 1649, 1645, 1640, 1636, 1631, 1627, 1623, 1618, + 1614, 1610, 1606, 1601, 1597, 1593, 1589, 1585, 1581, 1577, + 1573, 1569, 1565, 1561, 1557, 1554, 1550, 1546, 1542, 1539, + 1535, 1531, 1528, 1524, 1520, 1517, 1513, 1510, 1506, 1503, + 1500, + }; + expected_table.resize(table.SLOPE_TABLE_SIZE, 1500); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.scan_steps, 224u); + ASSERT_EQ(table.pixeltime_sum, 734910u); +} + +void test_create_slope_table_large_half_step() +{ + // created approximately from Canon 8600F table, see the full step test for the data + + MotorSlope slope; + slope.initial_speed_w = 54612; + slope.max_speed_w = 1500; + slope.acceleration = 1.013948e-9; + + auto table = create_slope_table(slope, 3000, StepType::HALF, 4, 8); + + std::vector expected_table = { + 27306, 27306, 10285, 7545, 6240, 5440, 4885, 4471, 4147, 3885, + 3667, 3482, 3322, 3183, 3060, 2950, 2851, 2761, 2679, 2605, + 2536, 2472, 2413, 2358, 2306, 2258, 2213, 2170, 2130, 2092, + 2055, 2021, 1988, 1957, 1927, 1899, 1872, 1846, 1821, 1797, + 1774, 1751, 1730, 1709, 1689, 1670, 1652, 1634, 1616, 1599, + 1583, 1567, 1552, 1537, 1522, 1508, 1500, + }; + expected_table.resize(table.SLOPE_TABLE_SIZE, 1500); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.scan_steps, 60u); + ASSERT_EQ(table.pixeltime_sum, 206294u); + + + table = create_slope_table(slope, 1500, StepType::HALF, 4, 8); + + expected_table = { + 27306, 27306, 10285, 7545, 6240, 5440, 4885, 4471, 4147, 3885, + 3667, 3482, 3322, 3183, 3060, 2950, 2851, 2761, 2679, 2605, + 2536, 2472, 2413, 2358, 2306, 2258, 2213, 2170, 2130, 2092, + 2055, 2021, 1988, 1957, 1927, 1899, 1872, 1846, 1821, 1797, + 1774, 1751, 1730, 1709, 1689, 1670, 1652, 1634, 1616, 1599, + 1583, 1567, 1552, 1537, 1522, 1508, 1494, 1481, 1468, 1455, + 1443, 1431, 1419, 1408, 1397, 1386, 1375, 1364, 1354, 1344, + 1335, 1325, 1316, 1307, 1298, 1289, 1280, 1272, 1263, 1255, + 1247, 1240, 1232, 1224, 1217, 1210, 1203, 1196, 1189, 1182, + 1175, 1169, 1162, 1156, 1150, 1144, 1138, 1132, 1126, 1120, + 1114, 1109, 1103, 1098, 1093, 1087, 1082, 1077, 1072, 1067, + 1062, 1057, 1053, 1048, 1043, 1039, 1034, 1030, 1025, 1021, + 1017, 1012, 1008, 1004, 1000, 996, 992, 988, 984, 980, + 976, 973, 969, 965, 962, 958, 955, 951, 948, 944, + 941, 937, 934, 931, 927, 924, 921, 918, 915, 912, + 909, 906, 903, 900, 897, 894, 891, 888, 885, 882, + 880, 877, 874, 871, 869, 866, 863, 861, 858, 856, + 853, 851, 848, 846, 843, 841, 838, 836, 834, 831, + 829, 827, 824, 822, 820, 818, 815, 813, 811, 809, + 807, 805, 803, 800, 798, 796, 794, 792, 790, 788, + 786, 784, 782, 780, 778, 777, 775, 773, 771, 769, + 767, 765, 764, 762, 760, 758, 756, 755, 753, 751, + 750, + }; + expected_table.resize(table.SLOPE_TABLE_SIZE, 750); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.scan_steps, 224u); + ASSERT_EQ(table.pixeltime_sum, 367399u); +} + +void test_motor() +{ + test_create_slope_table3(); + test_create_slope_table_small_full_step(); + test_create_slope_table_small_full_step_target_speed_too_high(); + test_create_slope_table_small_half_step(); + test_create_slope_table_large_full_step(); + test_create_slope_table_large_half_step(); +} + +} // namespace genesys