diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index e4f73b46c..09dc84e70 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -62,6 +62,10 @@ #include "genesys.h" #include "conv.h" +#include "gl124_registers.h" +#include "gl843_registers.h" +#include "gl846_registers.h" +#include "gl847_registers.h" #include "usb_device.h" #include "utilities.h" #include "scanner_interface_usb.h" @@ -867,6 +871,217 @@ void sanei_genesys_search_reference_point(Genesys_Device* dev, Genesys_Sensor& s sensor.ccd_start_xoffset, left, top); } +namespace gl843 { + void gl843_park_xpa_lamp(Genesys_Device* dev); + void gl843_stop_action(Genesys_Device* dev); +} // namespace gl843 + +namespace gl846 { + void gl846_stop_action(Genesys_Device* dev); +} // namespace gl846 + +namespace gl847 { + void gl847_stop_action(Genesys_Device* dev); +} // namespace gl847 + +namespace gl124 { + void gl124_feed(Genesys_Device* dev, unsigned int steps, int reverse); + void gl124_setup_scan_gpio(Genesys_Device* dev, int resolution); + void gl124_stop_action(Genesys_Device* dev); +} // namespace gl124 + +void scanner_clear_scan_and_feed_counts(Genesys_Device& dev) +{ + switch (dev.model->asic_type) { + case AsicType::GL843: { + dev.interface->write_register(gl843::REG_0x0D, + gl843::REG_0x0D_CLRLNCNT | gl843::REG_0x0D_CLRMCNT); + break; + } + case AsicType::GL845: + case AsicType::GL846: { + dev.interface->write_register(gl846::REG_0x0D, + gl846::REG_0x0D_CLRLNCNT | gl846::REG_0x0D_CLRMCNT); + break; + } + case AsicType::GL847:{ + dev.interface->write_register(gl847::REG_0x0D, + gl847::REG_0x0D_CLRLNCNT | gl847::REG_0x0D_CLRMCNT); + break; + } + case AsicType::GL124:{ + dev.interface->write_register(gl124::REG_0x0D, + gl124::REG_0x0D_CLRLNCNT | gl124::REG_0x0D_CLRMCNT); + break; + } + default: + throw SaneException("Unsupported asic type"); + } +} + +void scanner_stop_action(Genesys_Device& dev) +{ + switch (dev.model->asic_type) { + case AsicType::GL843: { + gl843::gl843_stop_action(&dev); + break; + } + case AsicType::GL845: + case AsicType::GL846: { + gl846::gl846_stop_action(&dev); + break; + } + case AsicType::GL847:{ + gl847::gl847_stop_action(&dev); + break; + } + case AsicType::GL124:{ + gl124::gl124_stop_action(&dev); + break; + } + default: + throw SaneException("Unsupported asic type"); + } +} + +void scanner_slow_back_home(Genesys_Device& dev, bool wait_until_home) +{ + DBG_HELPER_ARGS(dbg, "wait_until_home = %d", wait_until_home); + + switch (dev.model->asic_type) { + case AsicType::GL843: + case AsicType::GL845: + case AsicType::GL846: + case AsicType::GL847: + case AsicType::GL124: + break; + default: + throw SaneException("Unsupported asic type"); + } + + if (dev.needs_home_ta) { + gl843::gl843_park_xpa_lamp(&dev); + } + + if (dev.cmd_set->needs_update_home_sensor_gpio()) { + dev.cmd_set->update_home_sensor_gpio(dev); + } + + auto status = scanner_read_reliable_status(dev); + + if (dev.model->asic_type == AsicType::GL843) { + dev.scanhead_position_in_steps = 0; + } + + if (status.is_at_home) { + dbg.log(DBG_info, "already at home"); + dev.scanhead_position_in_steps = 0; + return; + } + + if (dev.model->model_id == ModelId::CANON_LIDE_210) { + // feed a little first + gl124::gl124_feed(&dev, 20, true); + } + + Genesys_Register_Set local_reg = dev.reg; + unsigned resolution = sanei_genesys_get_lowest_ydpi(&dev); + + const auto& sensor = sanei_genesys_find_sensor(&dev, resolution, 1, dev.model->default_method); + + ScanSession session; + session.params.xres = resolution; + session.params.yres = resolution; + session.params.startx = 100; + if (dev.model->asic_type == AsicType::GL843) { + session.params.starty = 40000; + } else { + session.params.starty = 30000; + } + session.params.pixels = 100; + session.params.lines = 100; + session.params.depth = 8; + session.params.channels = 1; + session.params.scan_method = dev.settings.scan_method; + if (dev.model->asic_type == AsicType::GL843) { + session.params.scan_mode = ScanColorMode::LINEART; + session.params.color_filter = dev.settings.color_filter; + } else { + session.params.scan_mode = ScanColorMode::GRAY; + session.params.color_filter = ColorFilter::RED; + } + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE | + ScanFlag::REVERSE; + if (dev.model->asic_type == AsicType::GL843) { + session.params.flags |= ScanFlag::DISABLE_BUFFER_FULL_MOVE; + } + + compute_session(&dev, session, sensor); + + dev.cmd_set->init_regs_for_scan_session(&dev, sensor, &local_reg, session); + + scanner_clear_scan_and_feed_counts(dev); + + // FIXME: why we do differently than other asics here? + if (dev.model->asic_type == AsicType::GL843) { + local_reg.find_reg(gl843::REG_0x01).value &= ~gl843::REG_0x01_SCAN; + } + + dev.interface->write_registers(local_reg); + + if (dev.model->asic_type == AsicType::GL124) { + gl124::gl124_setup_scan_gpio(&dev, resolution); + } + + try { + scanner_start_action(dev, true); + } catch (...) { + catch_all_exceptions(__func__, [&]() { scanner_stop_action(dev); }); + // restore original registers + catch_all_exceptions(__func__, [&]() + { + dev.interface->write_registers(dev.reg); + }); + throw; + } + + if (dev.cmd_set->needs_update_home_sensor_gpio()) { + dev.cmd_set->update_home_sensor_gpio(dev); + } + + if (is_testing_mode()) { + dev.interface->test_checkpoint("slow_back_home"); + return; + } + + if (wait_until_home) { + for (unsigned i = 0; i < 300; ++i) { + auto status = scanner_read_status(dev); + + if (status.is_at_home) { + dbg.log(DBG_info, "reached home position"); + if (dev.model->asic_type == AsicType::GL846 || + dev.model->asic_type == AsicType::GL847) + { + scanner_stop_action(dev); + } + dev.scanhead_position_in_steps = 0; + return; + } + + dev.interface->sleep_ms(100); + } + + // when we come here then the scanner needed too much time for this, so we better stop + // the motor + catch_all_exceptions(__func__, [&](){ scanner_stop_action(dev); }); + throw SaneException(SANE_STATUS_IO_ERROR, "timeout while waiting for scanhead to go home"); + } + dbg.log(DBG_info, "scanhead is still moving"); +} + void sanei_genesys_calculate_zmod(bool two_table, uint32_t exposure_time, const std::vector& slope_table, diff --git a/backend/genesys/gl124.cpp b/backend/genesys/gl124.cpp index 74946d093..4a81dd213 100644 --- a/backend/genesys/gl124.cpp +++ b/backend/genesys/gl124.cpp @@ -1000,7 +1000,7 @@ void CommandSetGl124::set_powersaving(Genesys_Device* dev, int delay /* in minut } } -static void gl124_stop_action(Genesys_Device* dev) +void gl124_stop_action(Genesys_Device* dev) { DBG_HELPER(dbg); std::uint8_t val40; @@ -1056,7 +1056,7 @@ static void gl124_stop_action(Genesys_Device* dev) * @param *dev device to set up * @param resolution dpi of the target scan */ -static void gl124_setup_scan_gpio(Genesys_Device* dev, int resolution) +void gl124_setup_scan_gpio(Genesys_Device* dev, int resolution) { DBG_HELPER(dbg); @@ -1178,97 +1178,7 @@ void CommandSetGl124::rewind(Genesys_Device* dev) const */ void CommandSetGl124::slow_back_home(Genesys_Device* dev, bool wait_until_home) const { - DBG_HELPER_ARGS(dbg, "wait_until_home = %d", wait_until_home); - Genesys_Register_Set local_reg; - int loop = 0; - - // post scan gpio : without that HOMSNR is unreliable - dev->cmd_set->update_home_sensor_gpio(*dev); - auto status = scanner_read_reliable_status(*dev); - - if (status.is_at_home) { - DBG (DBG_info, "%s: already at home, completed\n", __func__); - dev->scanhead_position_in_steps = 0; - return; - } - - // feed a little first - if (dev->model->model_id == ModelId::CANON_LIDE_210) { - gl124_feed(dev, 20, true); - } - - local_reg = dev->reg; - unsigned resolution = sanei_genesys_get_lowest_dpi(dev); - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - ScanSession session; - session.params.xres = resolution; - session.params.yres = resolution; - session.params.startx = 100; - session.params.starty = 30000; - session.params.pixels = 100; - session.params.lines = 100; - session.params.depth = 8; - session.params.channels = 1; - session.params.scan_method = dev->settings.scan_method; - session.params.scan_mode = ScanColorMode::GRAY; - session.params.color_filter = ColorFilter::RED; - session.params.flags = ScanFlag::DISABLE_SHADING | - ScanFlag::DISABLE_GAMMA | - ScanFlag::IGNORE_LINE_DISTANCE | - ScanFlag::REVERSE; - compute_session(dev, session, sensor); - - init_regs_for_scan_session(dev, sensor, &local_reg, session); - - // clear scan and feed count - dev->interface->write_register(REG_0x0D, REG_0x0D_CLRLNCNT | REG_0x0D_CLRMCNT); - - - dev->interface->write_registers(local_reg); - - gl124_setup_scan_gpio(dev,resolution); - - try { - scanner_start_action(*dev, true); - } catch (...) { - catch_all_exceptions(__func__, [&]() { gl124_stop_action(dev); }); - // restore original registers - catch_all_exceptions(__func__, [&]() - { - dev->interface->write_registers(dev->reg); - }); - throw; - } - - update_home_sensor_gpio(*dev); - if (is_testing_mode()) { - dev->interface->test_checkpoint("slow_back_home"); - return; - } - - if (wait_until_home) - { - - while (loop < 300) { - status = scanner_read_status(*dev); - - if (status.is_at_home) { - DBG(DBG_info, "%s: reached home position\n", __func__); - dev->scanhead_position_in_steps = 0; - return; - } - dev->interface->sleep_ms(100); - ++loop; - } - - /* when we come here then the scanner needed too much time for this, so we better stop the motor */ - gl124_stop_action (dev); - throw SaneException(SANE_STATUS_IO_ERROR, "timeout while waiting for scanhead to go home"); - } - - DBG(DBG_info, "%s: scanhead is still moving\n", __func__); + scanner_slow_back_home(*dev, wait_until_home); } /** @brief moves the slider to steps at motor base dpi @@ -1276,7 +1186,7 @@ void CommandSetGl124::slow_back_home(Genesys_Device* dev, bool wait_until_home) * @param steps number of steps to move * @param reverse true is moving backward * */ -static void gl124_feed(Genesys_Device* dev, unsigned int steps, int reverse) +void gl124_feed(Genesys_Device* dev, unsigned int steps, int reverse) { DBG_HELPER_ARGS(dbg, "steps=%d", steps); Genesys_Register_Set local_reg; diff --git a/backend/genesys/gl124.h b/backend/genesys/gl124.h index 711ba067f..a734e4d42 100644 --- a/backend/genesys/gl124.h +++ b/backend/genesys/gl124.h @@ -109,9 +109,9 @@ static Memory_layout layouts[]={ } }; -static void gl124_feed(Genesys_Device* dev, unsigned int steps, int reverse); +void gl124_feed(Genesys_Device* dev, unsigned int steps, int reverse); -static void gl124_stop_action(Genesys_Device* dev); +void gl124_stop_action(Genesys_Device* dev); static void gl124_send_slope_table(Genesys_Device* dev, int table_nr, const std::vector& slope_table, int steps); diff --git a/backend/genesys/gl843.cpp b/backend/genesys/gl843.cpp index 753b4d7ef..59e1a34f1 100644 --- a/backend/genesys/gl843.cpp +++ b/backend/genesys/gl843.cpp @@ -1325,7 +1325,7 @@ static void gl843_stop_action_no_move(Genesys_Device* dev, Genesys_Register_Set* dev->interface->sleep_ms(100); } -static void gl843_stop_action(Genesys_Device* dev) +void gl843_stop_action(Genesys_Device* dev) { DBG_HELPER(dbg); unsigned int loop; @@ -1727,7 +1727,7 @@ void CommandSetGl843::end_scan(Genesys_Device* dev, Genesys_Register_Set* reg, /** @brief park XPA lamp * park the XPA lamp if needed */ -static void gl843_park_xpa_lamp(Genesys_Device* dev) +void gl843_park_xpa_lamp(Genesys_Device* dev) { DBG_HELPER(dbg); Genesys_Register_Set local_reg; @@ -1788,99 +1788,7 @@ static void gl843_park_xpa_lamp(Genesys_Device* dev) * */ void CommandSetGl843::slow_back_home(Genesys_Device* dev, bool wait_until_home) const { - DBG_HELPER_ARGS(dbg, "wait_until_home = %d", wait_until_home); - Genesys_Register_Set local_reg; - GenesysRegister *r; - int loop = 0; - - if (dev->needs_home_ta) { - gl843_park_xpa_lamp(dev); - } - - /* regular slow back home */ - dev->scanhead_position_in_steps = 0; - - auto status = scanner_read_reliable_status(*dev); - - if (status.is_at_home) { - return; - } - - local_reg = dev->reg; - unsigned resolution = sanei_genesys_get_lowest_ydpi(dev); - - const auto& sensor = sanei_genesys_find_sensor(dev, resolution, 1, dev->model->default_method); - - ScanSession session; - session.params.xres = resolution; - session.params.yres = resolution; - session.params.startx = 100; - session.params.starty = 40000; - session.params.pixels = 100; - session.params.lines = 100; - session.params.depth = 8; - session.params.channels = 1; - 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 = ScanFlag::DISABLE_SHADING | - ScanFlag::DISABLE_GAMMA | - ScanFlag::DISABLE_BUFFER_FULL_MOVE | - ScanFlag::IGNORE_LINE_DISTANCE | - ScanFlag::REVERSE; - compute_session(dev, session, sensor); - - init_regs_for_scan_session(dev, sensor, &local_reg, session); - - // clear scan and feed count - dev->interface->write_register(REG_0x0D, REG_0x0D_CLRLNCNT | REG_0x0D_CLRMCNT); - - // set up for no scan - r = sanei_genesys_get_address(&local_reg, REG_0x01); - r->value &= ~REG_0x01_SCAN; - - dev->interface->write_registers(local_reg); - - try { - scanner_start_action(*dev, true); - } catch (...) { - catch_all_exceptions(__func__, [&]() { gl843_stop_action(dev); }); - // restore original registers - catch_all_exceptions(__func__, [&]() - { - dev->interface->write_registers(dev->reg); - }); - throw; - } - - if (is_testing_mode()) { - dev->interface->test_checkpoint("slow_back_home"); - return; - } - - if (wait_until_home) - { - - while (loop < 300) /* do not wait longer then 30 seconds */ - { - auto status = scanner_read_status(*dev); - - if (status.is_at_home) { - DBG(DBG_info, "%s: reached home position\n", __func__); - DBG(DBG_proc, "%s: finished\n", __func__); - return; - } - dev->interface->sleep_ms(100); - ++loop; - } - - // when we come here then the scanner needed too much time for this, so we better stop - // the motor - catch_all_exceptions(__func__, [&](){ gl843_stop_action(dev); }); - throw SaneException(SANE_STATUS_IO_ERROR, "timeout while waiting for scanhead to go home"); - } - - DBG(DBG_info, "%s: scanhead is still moving\n", __func__); + scanner_slow_back_home(*dev, wait_until_home); } // Automatically set top-left edge of the scan area by scanning a 200x200 pixels area at 600 dpi diff --git a/backend/genesys/gl846.cpp b/backend/genesys/gl846.cpp index 11c38f7c4..42d7a2c54 100644 --- a/backend/genesys/gl846.cpp +++ b/backend/genesys/gl846.cpp @@ -840,7 +840,7 @@ void CommandSetGl846::set_powersaving(Genesys_Device* dev, int delay /* in minut DBG_HELPER_ARGS(dbg, "delay = %d", delay); } -static void gl846_stop_action(Genesys_Device* dev) +void gl846_stop_action(Genesys_Device* dev) { DBG_HELPER(dbg); unsigned int loop; @@ -931,96 +931,7 @@ void CommandSetGl846::end_scan(Genesys_Device* dev, Genesys_Register_Set* reg, // Moves the slider to the home (top) postion slowly void CommandSetGl846::slow_back_home(Genesys_Device* dev, bool wait_until_home) const { - DBG_HELPER_ARGS(dbg, "wait_until_home = %d", wait_until_home); - Genesys_Register_Set local_reg; - int loop = 0; - - update_home_sensor_gpio(*dev); - - // first read gives HOME_SENSOR true - auto status = scanner_read_reliable_status(*dev); - - /* is sensor at home? */ - if (status.is_at_home) { - DBG(DBG_info, "%s: already at home, completed\n", __func__); - dev->scanhead_position_in_steps = 0; - return; - } - - local_reg = dev->reg; - - unsigned resolution = sanei_genesys_get_lowest_ydpi(dev); - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - ScanSession session; - session.params.xres = resolution; - session.params.yres = resolution; - session.params.startx = 100; - session.params.starty = 30000; - session.params.pixels = 100; - session.params.lines = 100; - session.params.depth = 8; - session.params.channels = 1; - session.params.scan_method = dev->settings.scan_method; - session.params.scan_mode = ScanColorMode::GRAY; - session.params.color_filter = ColorFilter::RED; - session.params.flags = ScanFlag::DISABLE_SHADING | - ScanFlag::DISABLE_GAMMA | - ScanFlag::IGNORE_LINE_DISTANCE | - ScanFlag::REVERSE; - compute_session(dev, session, sensor); - - init_regs_for_scan_session(dev, sensor, &local_reg, session); - - // clear scan and feed count - dev->interface->write_register(REG_0x0D, REG_0x0D_CLRLNCNT | REG_0x0D_CLRMCNT); - - dev->interface->write_registers(local_reg); - - try { - scanner_start_action(*dev, true); - } catch (...) { - try { - gl846_stop_action(dev); - } catch (...) {} - // restore original registers - catch_all_exceptions(__func__, [&]() - { - dev->interface->write_registers(dev->reg); - }); - throw; - } - - update_home_sensor_gpio(*dev); - - if (is_testing_mode()) { - dev->interface->test_checkpoint("slow_back_home"); - return; - } - - if (wait_until_home) - { - while (loop < 300) /* do not wait longer then 30 seconds */ - { - auto status = scanner_read_status(*dev); - if (status.is_at_home) { - DBG(DBG_info, "%s: reached home position\n", __func__); - gl846_stop_action (dev); - dev->scanhead_position_in_steps = 0; - return; - } - dev->interface->sleep_ms(100); - ++loop; - } - - // when we come here then the scanner needed too much time for this, so we better stop - // the motor - catch_all_exceptions(__func__, [&](){ gl846_stop_action(dev); }); - throw SaneException(SANE_STATUS_IO_ERROR, "timeout while waiting for scanhead to go home"); - } - - DBG(DBG_info, "%s: scanhead is still moving\n", __func__); + scanner_slow_back_home(*dev, wait_until_home); } // Automatically set top-left edge of the scan area by scanning a 200x200 pixels area at 600 dpi diff --git a/backend/genesys/gl846.h b/backend/genesys/gl846.h index 04ab01467..3995b1071 100644 --- a/backend/genesys/gl846.h +++ b/backend/genesys/gl846.h @@ -56,7 +56,7 @@ namespace gl846 { * */ static void gl846_feed(Genesys_Device* dev, unsigned int steps); -static void gl846_stop_action(Genesys_Device* dev); +void gl846_stop_action(Genesys_Device* dev); diff --git a/backend/genesys/gl847.cpp b/backend/genesys/gl847.cpp index 7a03049a8..7e901ed40 100644 --- a/backend/genesys/gl847.cpp +++ b/backend/genesys/gl847.cpp @@ -844,7 +844,7 @@ void CommandSetGl847::set_powersaving(Genesys_Device* dev, int delay /* in minut DBG_HELPER_ARGS(dbg, "delay = %d", delay); } -static void gl847_stop_action(Genesys_Device* dev) +void gl847_stop_action(Genesys_Device* dev) { DBG_HELPER(dbg); uint8_t val; @@ -977,93 +977,7 @@ static void gl847_rewind(Genesys_Device* dev) */ void CommandSetGl847::slow_back_home(Genesys_Device* dev, bool wait_until_home) const { - DBG_HELPER_ARGS(dbg, "wait_until_home = %d", wait_until_home); - Genesys_Register_Set local_reg; - int loop = 0; - - update_home_sensor_gpio(*dev); - - // first read gives HOME_SENSOR true - auto status = scanner_read_reliable_status(*dev); - - if (status.is_at_home) { - DBG(DBG_info, "%s: already at home, completed\n", __func__); - dev->scanhead_position_in_steps = 0; - return; - } - - local_reg = dev->reg; - - unsigned resolution = sanei_genesys_get_lowest_ydpi(dev); - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - ScanSession session; - session.params.xres = resolution; - session.params.yres = resolution; - session.params.startx = 100; - session.params.starty = 30000; - session.params.pixels = 100; - session.params.lines = 100; - session.params.depth = 8; - session.params.channels = 1; - session.params.scan_method = dev->settings.scan_method; - session.params.scan_mode = ScanColorMode::GRAY; - session.params.color_filter = ColorFilter::RED; - session.params.flags = ScanFlag::DISABLE_SHADING | - ScanFlag::DISABLE_GAMMA | - ScanFlag::IGNORE_LINE_DISTANCE | - ScanFlag::REVERSE; - compute_session(dev, session, sensor); - - init_regs_for_scan_session(dev, sensor, &local_reg, session); - - // clear scan and feed count - dev->interface->write_register(REG_0x0D, REG_0x0D_CLRLNCNT | REG_0x0D_CLRMCNT); - - dev->interface->write_registers(local_reg); - - try { - scanner_start_action(*dev, true); - } catch (...) { - catch_all_exceptions(__func__, [&]() { gl847_stop_action(dev); }); - // restore original registers - catch_all_exceptions(__func__, [&]() - { - dev->interface->write_registers(dev->reg); - }); - throw; - } - - update_home_sensor_gpio(*dev); - - if (is_testing_mode()) { - dev->interface->test_checkpoint("slow_back_home"); - return; - } - - if (wait_until_home) - { - while (loop < 300) /* do not wait longer then 30 seconds */ - { - auto status = scanner_read_status(*dev); - if (status.is_at_home) { - DBG(DBG_info, "%s: reached home position\n", __func__); - gl847_stop_action (dev); - dev->scanhead_position_in_steps = 0; - return; - } - dev->interface->sleep_ms(100); - ++loop; - } - - // when we come here then the scanner needed too much time for this, so we better stop - // the motor - catch_all_exceptions(__func__, [&](){ gl847_stop_action(dev); }); - throw SaneException(SANE_STATUS_IO_ERROR, "timeout while waiting for scanhead to go home"); - } - - DBG(DBG_info, "%s: scanhead is still moving\n", __func__); + scanner_slow_back_home(*dev, wait_until_home); } // Automatically set top-left edge of the scan area by scanning a 200x200 pixels area at 600 dpi diff --git a/backend/genesys/low.h b/backend/genesys/low.h index db1206ae9..f1372d3ad 100644 --- a/backend/genesys/low.h +++ b/backend/genesys/low.h @@ -352,6 +352,8 @@ extern void sanei_genesys_search_reference_point(Genesys_Device* dev, Genesys_Se const uint8_t* src_data, int start_pixel, int dpi, int width, int height); +void scanner_slow_back_home(Genesys_Device& dev, bool wait_until_home); + extern void sanei_genesys_write_file(const char* filename, const std::uint8_t* data, std::size_t length);