kopia lustrzana https://gitlab.com/sane-project/backends
Merge branch 'genesys-refactor-motor-handling' into 'master'
genesys: Refactor motor handling See merge request sane-project/backends!308merge-requests/317/merge
commit
8d07515bea
|
@ -504,6 +504,7 @@ libgenesys_la_SOURCES = genesys/genesys.cpp genesys/genesys.h \
|
|||
genesys/buffer.h genesys/buffer.cpp \
|
||||
genesys/calibration.h \
|
||||
genesys/command_set.h \
|
||||
genesys/command_set_common.h genesys/command_set_common.cpp \
|
||||
genesys/conv.h genesys/conv.cpp \
|
||||
genesys/device.h genesys/device.cpp \
|
||||
genesys/enums.h genesys/enums.cpp \
|
||||
|
|
|
@ -159,6 +159,13 @@ public:
|
|||
|
||||
/// cold boot init function
|
||||
virtual void asic_boot(Genesys_Device* dev, bool cold) const = 0;
|
||||
|
||||
/// enables or disables XPA slider motor
|
||||
virtual void set_xpa_lamp_power(Genesys_Device& dev, bool set) const = 0;
|
||||
|
||||
/// enables or disables XPA slider motor
|
||||
virtual void set_motor_mode(Genesys_Device& dev, Genesys_Register_Set& regs,
|
||||
MotorMode mode) const = 0;
|
||||
};
|
||||
|
||||
} // namespace genesys
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
|
||||
|
||||
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 "command_set_common.h"
|
||||
|
||||
namespace genesys {
|
||||
|
||||
CommandSetCommon::~CommandSetCommon() = default;
|
||||
|
||||
void CommandSetCommon::set_xpa_lamp_power(Genesys_Device& dev, bool set) const
|
||||
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
|
||||
struct LampSettings {
|
||||
ModelId model_id;
|
||||
ScanMethod scan_method;
|
||||
GenesysRegisterSettingSet regs_on;
|
||||
GenesysRegisterSettingSet regs_off;
|
||||
};
|
||||
|
||||
// FIXME: BUG: we're not clearing the registers to the previous state when returning back when
|
||||
// turning off the lamp
|
||||
LampSettings settings[] = {
|
||||
{ ModelId::CANON_8400F, ScanMethod::TRANSPARENCY, {
|
||||
{ 0xa6, 0x34, 0xf4 },
|
||||
}, {
|
||||
{ 0xa6, 0x40, 0x70 },
|
||||
}
|
||||
},
|
||||
{ ModelId::CANON_8400F, ScanMethod::TRANSPARENCY_INFRARED, {
|
||||
{ 0x6c, 0x40, 0x40 },
|
||||
{ 0xa6, 0x01, 0xff },
|
||||
}, {
|
||||
{ 0x6c, 0x00, 0x40 },
|
||||
{ 0xa6, 0x00, 0xff },
|
||||
}
|
||||
},
|
||||
{ ModelId::CANON_8600F, ScanMethod::TRANSPARENCY, {
|
||||
{ 0xa6, 0x34, 0xf4 },
|
||||
{ 0xa7, 0xe0, 0xe0 },
|
||||
}, {
|
||||
{ 0xa6, 0x40, 0x70 },
|
||||
}
|
||||
},
|
||||
{ ModelId::CANON_8600F, ScanMethod::TRANSPARENCY_INFRARED, {
|
||||
{ 0xa6, 0x00, 0xc0 },
|
||||
{ 0xa7, 0xe0, 0xe0 },
|
||||
{ 0x6c, 0x80, 0x80 },
|
||||
}, {
|
||||
{ 0xa6, 0x00, 0xc0 },
|
||||
{ 0x6c, 0x00, 0x80 },
|
||||
}
|
||||
},
|
||||
{ ModelId::PLUSTEK_OPTICFILM_7200I, ScanMethod::TRANSPARENCY, {
|
||||
}, {
|
||||
{ 0xa6, 0x40, 0x70 }, // BUG: remove this cleanup write, it was enabled by accident
|
||||
}
|
||||
},
|
||||
{ ModelId::PLUSTEK_OPTICFILM_7200I, ScanMethod::TRANSPARENCY_INFRARED, {
|
||||
{ 0xa8, 0x07, 0x07 },
|
||||
}, {
|
||||
{ 0xa8, 0x00, 0x07 },
|
||||
}
|
||||
},
|
||||
{ ModelId::PLUSTEK_OPTICFILM_7300, ScanMethod::TRANSPARENCY, {}, {} },
|
||||
{ ModelId::PLUSTEK_OPTICFILM_7500I, ScanMethod::TRANSPARENCY, {}, {} },
|
||||
{ ModelId::PLUSTEK_OPTICFILM_7500I, ScanMethod::TRANSPARENCY_INFRARED, {
|
||||
{ 0xa8, 0x07, 0x07 },
|
||||
}, {
|
||||
{ 0xa8, 0x00, 0x07 },
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
for (const auto& setting : settings) {
|
||||
if (setting.model_id == dev.model->model_id &&
|
||||
setting.scan_method == dev.settings.scan_method)
|
||||
{
|
||||
apply_reg_settings_to_device(dev, set ? setting.regs_on : setting.regs_off);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// BUG: we're currently calling the function in shut down path of regular lamp
|
||||
if (set) {
|
||||
throw SaneException("Unexpected code path entered");
|
||||
}
|
||||
|
||||
GenesysRegisterSettingSet regs = {
|
||||
{ 0xa6, 0x40, 0x70 },
|
||||
};
|
||||
apply_reg_settings_to_device(dev, regs);
|
||||
// TODO: throw exception when we're only calling this function in error return path
|
||||
// throw SaneException("Could not find XPA lamp settings");
|
||||
}
|
||||
|
||||
|
||||
void CommandSetCommon::set_motor_mode(Genesys_Device& dev, Genesys_Register_Set& regs,
|
||||
MotorMode mode) const
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
|
||||
struct MotorSettings {
|
||||
ModelId model_id;
|
||||
ResolutionFilter resolutions;
|
||||
GenesysRegisterSettingSet regs_primary_and_secondary;
|
||||
GenesysRegisterSettingSet regs_primary;
|
||||
};
|
||||
|
||||
MotorSettings settings[] = {
|
||||
{ ModelId::CANON_8400F, { 400, 800, 1600 }, {
|
||||
{ 0x6c, 0x00, 0x90 },
|
||||
{ 0xa9, 0x04, 0x06 },
|
||||
}, {
|
||||
{ 0x6c, 0x90, 0x90 },
|
||||
{ 0xa9, 0x02, 0x06 },
|
||||
}
|
||||
},
|
||||
{ ModelId::CANON_8400F, { 3200 }, {
|
||||
{ 0x6c, 0x00, 0x92 },
|
||||
{ 0xa9, 0x04, 0x06 },
|
||||
}, {
|
||||
{ 0x6c, 0x90, 0x90 },
|
||||
{ 0xa9, 0x02, 0x06 },
|
||||
}
|
||||
},
|
||||
{ ModelId::CANON_8600F, { 300, 600, 1200 }, {
|
||||
{ 0x6c, 0x00, 0x20 },
|
||||
{ 0xa6, 0x01, 0x41 },
|
||||
}, {
|
||||
{ 0x6c, 0x20, 0x22 },
|
||||
{ 0xa6, 0x00, 0x41 },
|
||||
}
|
||||
},
|
||||
{ ModelId::CANON_8600F, { 2400, 4800 }, {
|
||||
{ 0x6c, 0x02, 0x22 },
|
||||
{ 0xa6, 0x01, 0x41 },
|
||||
}, {
|
||||
{ 0x6c, 0x20, 0x22 },
|
||||
{ 0xa6, 0x00, 0x41 },
|
||||
}
|
||||
},
|
||||
{ ModelId::HP_SCANJET_G4050, ResolutionFilter::ANY, {
|
||||
{ 0x6b, 0x81, 0x81 }, // set MULTFILM and GPOADF
|
||||
{ 0x6c, 0x00, 0x40 }, // note that reverse change is not applied on off
|
||||
// 0xa6 register 0x08 bit likely sets motor power. No move at all without that one
|
||||
{ 0xa6, 0x08, 0x08 }, // note that reverse change is not applied on off
|
||||
{ 0xa8, 0x00, 0x04 },
|
||||
{ 0xa9, 0x30, 0x30 },
|
||||
}, {
|
||||
{ 0x6b, 0x00, 0x01 }, // BUG: note that only ADF is unset
|
||||
{ 0xa8, 0x04, 0x04 },
|
||||
{ 0xa9, 0x00, 0x10 }, // note that 0x20 bit is not reset
|
||||
}
|
||||
},
|
||||
{ ModelId::PLUSTEK_OPTICFILM_7200I, ResolutionFilter::ANY, {}, {} },
|
||||
{ ModelId::PLUSTEK_OPTICFILM_7300, ResolutionFilter::ANY, {}, {} },
|
||||
{ ModelId::PLUSTEK_OPTICFILM_7500I, ResolutionFilter::ANY, {}, {} },
|
||||
};
|
||||
|
||||
for (const auto& setting : settings) {
|
||||
if (setting.model_id == dev.model->model_id &&
|
||||
setting.resolutions.matches(dev.session.output_resolution))
|
||||
{
|
||||
switch (mode) {
|
||||
case MotorMode::PRIMARY: {
|
||||
apply_reg_settings_to_device(dev, setting.regs_primary);
|
||||
break;
|
||||
}
|
||||
case MotorMode::PRIMARY_AND_SECONDARY: {
|
||||
apply_reg_settings_to_device(dev, setting.regs_primary_and_secondary);
|
||||
break;
|
||||
}
|
||||
}
|
||||
regs.state.motor_mode = mode;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw SaneException("Motor settings have not been found");
|
||||
}
|
||||
|
||||
} // namespace genesys
|
|
@ -0,0 +1,46 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef BACKEND_GENESYS_COMMAND_SET_COMMON_H
|
||||
#define BACKEND_GENESYS_COMMAND_SET_COMMON_H
|
||||
|
||||
#include "command_set.h"
|
||||
|
||||
namespace genesys {
|
||||
|
||||
|
||||
/** Common command set functionality
|
||||
*/
|
||||
class CommandSetCommon : public CommandSet
|
||||
{
|
||||
public:
|
||||
~CommandSetCommon() override;
|
||||
|
||||
void set_xpa_lamp_power(Genesys_Device& dev, bool set) const override;
|
||||
|
||||
void set_motor_mode(Genesys_Device& dev, Genesys_Register_Set& regs,
|
||||
MotorMode mode) const override;
|
||||
};
|
||||
|
||||
} // namespace genesys
|
||||
|
||||
#endif // BACKEND_GENESYS_COMMAND_SET_COMMON_H
|
|
@ -124,10 +124,14 @@ unsigned Genesys_Device::head_pos(ScanHeadId scan_head) const
|
|||
}
|
||||
}
|
||||
|
||||
void Genesys_Device::set_head_pos_unknown()
|
||||
void Genesys_Device::set_head_pos_unknown(ScanHeadId scan_head)
|
||||
{
|
||||
is_head_pos_primary_known_ = false;
|
||||
is_head_pos_secondary_known_ = false;
|
||||
if ((scan_head & ScanHeadId::PRIMARY) != ScanHeadId::NONE) {
|
||||
is_head_pos_primary_known_ = false;
|
||||
}
|
||||
if ((scan_head & ScanHeadId::SECONDARY) != ScanHeadId::NONE) {
|
||||
is_head_pos_secondary_known_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Genesys_Device::set_head_pos_zero(ScanHeadId scan_head)
|
||||
|
@ -262,11 +266,25 @@ std::ostream& operator<<(std::ostream& out, const Genesys_Device& dev)
|
|||
|
||||
void apply_reg_settings_to_device(Genesys_Device& dev, const GenesysRegisterSettingSet& regs)
|
||||
{
|
||||
apply_reg_settings_to_device_with_backup(dev, regs);
|
||||
}
|
||||
|
||||
GenesysRegisterSettingSet
|
||||
apply_reg_settings_to_device_with_backup(Genesys_Device& dev,
|
||||
const GenesysRegisterSettingSet& regs)
|
||||
{
|
||||
GenesysRegisterSettingSet backup;
|
||||
for (const auto& reg : regs) {
|
||||
uint8_t val = dev.interface->read_register(reg.address);
|
||||
val = (val & ~reg.mask) | (reg.value & reg.mask);
|
||||
dev.interface->write_register(reg.address, val);
|
||||
std::uint8_t old_val = dev.interface->read_register(reg.address);
|
||||
std::uint8_t new_val = (old_val & ~reg.mask) | (reg.value & reg.mask);
|
||||
dev.interface->write_register(reg.address, new_val);
|
||||
|
||||
using SettingType = GenesysRegisterSettingSet::SettingType;
|
||||
backup.push_back(SettingType{reg.address,
|
||||
static_cast<std::uint8_t>(old_val & reg.mask),
|
||||
reg.mask});
|
||||
}
|
||||
return backup;
|
||||
}
|
||||
|
||||
} // namespace genesys
|
||||
|
|
|
@ -360,7 +360,7 @@ struct Genesys_Device
|
|||
|
||||
bool is_head_pos_known(ScanHeadId scan_head) const;
|
||||
unsigned head_pos(ScanHeadId scan_head) const;
|
||||
void set_head_pos_unknown();
|
||||
void set_head_pos_unknown(ScanHeadId scan_head);
|
||||
void set_head_pos_zero(ScanHeadId scan_head);
|
||||
void advance_head_pos_by_session(ScanHeadId scan_head);
|
||||
void advance_head_pos_by_steps(ScanHeadId scan_head, Direction direction, unsigned steps);
|
||||
|
@ -382,6 +382,10 @@ std::ostream& operator<<(std::ostream& out, const Genesys_Device& dev);
|
|||
|
||||
void apply_reg_settings_to_device(Genesys_Device& dev, const GenesysRegisterSettingSet& regs);
|
||||
|
||||
GenesysRegisterSettingSet
|
||||
apply_reg_settings_to_device_with_backup(Genesys_Device& dev,
|
||||
const GenesysRegisterSettingSet& regs);
|
||||
|
||||
} // namespace genesys
|
||||
|
||||
#endif
|
||||
|
|
|
@ -524,6 +524,11 @@ enum class Direction : unsigned
|
|||
BACKWARD = 1
|
||||
};
|
||||
|
||||
enum class MotorMode : unsigned
|
||||
{
|
||||
PRIMARY = 0,
|
||||
PRIMARY_AND_SECONDARY,
|
||||
};
|
||||
|
||||
} // namespace genesys
|
||||
|
||||
|
|
|
@ -718,11 +718,6 @@ 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_set_xpa_motor_power(Genesys_Device* dev, Genesys_Register_Set& regs, bool set);
|
||||
} // namespace gl843
|
||||
|
||||
namespace gl124 {
|
||||
void gl124_setup_scan_gpio(Genesys_Device* dev, int resolution);
|
||||
} // namespace gl124
|
||||
|
@ -969,14 +964,14 @@ void scanner_move(Genesys_Device& dev, ScanMethod scan_method, unsigned steps, D
|
|||
|
||||
dev.interface->write_registers(local_reg);
|
||||
if (uses_secondary_head) {
|
||||
gl843::gl843_set_xpa_motor_power(&dev, local_reg, true);
|
||||
dev.cmd_set->set_motor_mode(dev, local_reg, MotorMode::PRIMARY_AND_SECONDARY);
|
||||
}
|
||||
|
||||
try {
|
||||
scanner_start_action(dev, true);
|
||||
} catch (...) {
|
||||
catch_all_exceptions(__func__, [&]() {
|
||||
gl843::gl843_set_xpa_motor_power(&dev, local_reg, false);
|
||||
dev.cmd_set->set_motor_mode(dev, local_reg, MotorMode::PRIMARY);
|
||||
});
|
||||
catch_all_exceptions(__func__, [&]() { scanner_stop_action(dev); });
|
||||
// restore original registers
|
||||
|
@ -997,7 +992,7 @@ void scanner_move(Genesys_Device& dev, ScanMethod scan_method, unsigned steps, D
|
|||
scanner_stop_action(dev);
|
||||
}
|
||||
if (uses_secondary_head) {
|
||||
gl843::gl843_set_xpa_motor_power(&dev, local_reg, false);
|
||||
dev.cmd_set->set_motor_mode(dev, local_reg, MotorMode::PRIMARY);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1020,7 +1015,7 @@ void scanner_move(Genesys_Device& dev, ScanMethod scan_method, unsigned steps, D
|
|||
scanner_stop_action(dev);
|
||||
}
|
||||
if (uses_secondary_head) {
|
||||
gl843::gl843_set_xpa_motor_power(&dev, local_reg, false);
|
||||
dev.cmd_set->set_motor_mode(dev, local_reg, MotorMode::PRIMARY);
|
||||
}
|
||||
|
||||
dev.advance_head_pos_by_steps(ScanHeadId::PRIMARY, direction, steps);
|
||||
|
@ -1174,12 +1169,27 @@ void scanner_move_back_home(Genesys_Device& dev, bool wait_until_home)
|
|||
// 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); });
|
||||
dev.set_head_pos_unknown();
|
||||
dev.set_head_pos_unknown(ScanHeadId::PRIMARY | ScanHeadId::SECONDARY);
|
||||
throw SaneException(SANE_STATUS_IO_ERROR, "timeout while waiting for scanhead to go home");
|
||||
}
|
||||
dbg.log(DBG_info, "scanhead is still moving");
|
||||
}
|
||||
|
||||
namespace {
|
||||
void handle_motor_position_after_move_back_home_ta(Genesys_Device& dev)
|
||||
{
|
||||
if (dev.is_head_pos_known(ScanHeadId::PRIMARY)) {
|
||||
if (dev.head_pos(ScanHeadId::PRIMARY) > dev.head_pos(ScanHeadId::SECONDARY)) {
|
||||
dev.advance_head_pos_by_steps(ScanHeadId::PRIMARY, Direction::BACKWARD,
|
||||
dev.head_pos(ScanHeadId::SECONDARY));
|
||||
} else {
|
||||
dev.set_head_pos_zero(ScanHeadId::PRIMARY);
|
||||
}
|
||||
dev.set_head_pos_zero(ScanHeadId::SECONDARY);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void scanner_move_back_home_ta(Genesys_Device& dev)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
|
@ -1230,7 +1240,7 @@ void scanner_move_back_home_ta(Genesys_Device& dev)
|
|||
scanner_clear_scan_and_feed_counts(dev);
|
||||
|
||||
dev.interface->write_registers(local_reg);
|
||||
gl843::gl843_set_xpa_motor_power(&dev, local_reg, true);
|
||||
dev.cmd_set->set_motor_mode(dev, local_reg, MotorMode::PRIMARY_AND_SECONDARY);
|
||||
|
||||
try {
|
||||
scanner_start_action(dev, true);
|
||||
|
@ -1244,18 +1254,10 @@ void scanner_move_back_home_ta(Genesys_Device& dev)
|
|||
if (is_testing_mode()) {
|
||||
dev.interface->test_checkpoint("move_back_home_ta");
|
||||
|
||||
if (dev.is_head_pos_known(ScanHeadId::PRIMARY)) {
|
||||
if (dev.head_pos(ScanHeadId::PRIMARY) > dev.head_pos(ScanHeadId::SECONDARY)) {
|
||||
dev.advance_head_pos_by_steps(ScanHeadId::PRIMARY, Direction::BACKWARD,
|
||||
dev.head_pos(ScanHeadId::SECONDARY));
|
||||
} else {
|
||||
dev.set_head_pos_zero(ScanHeadId::PRIMARY);
|
||||
}
|
||||
dev.set_head_pos_zero(ScanHeadId::SECONDARY);
|
||||
}
|
||||
handle_motor_position_after_move_back_home_ta(dev);
|
||||
|
||||
scanner_stop_action(dev);
|
||||
gl843::gl843_set_xpa_motor_power(&dev, local_reg, false);
|
||||
dev.cmd_set->set_motor_mode(dev, local_reg, MotorMode::PRIMARY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1266,18 +1268,10 @@ void scanner_move_back_home_ta(Genesys_Device& dev)
|
|||
if (status.is_at_home) {
|
||||
dbg.log(DBG_info, "TA reached home position");
|
||||
|
||||
if (dev.is_head_pos_known(ScanHeadId::PRIMARY)) {
|
||||
if (dev.head_pos(ScanHeadId::PRIMARY) > dev.head_pos(ScanHeadId::SECONDARY)) {
|
||||
dev.advance_head_pos_by_steps(ScanHeadId::PRIMARY, Direction::BACKWARD,
|
||||
dev.head_pos(ScanHeadId::SECONDARY));
|
||||
} else {
|
||||
dev.set_head_pos_zero(ScanHeadId::PRIMARY);
|
||||
}
|
||||
dev.set_head_pos_zero(ScanHeadId::SECONDARY);
|
||||
}
|
||||
handle_motor_position_after_move_back_home_ta(dev);
|
||||
|
||||
scanner_stop_action(dev);
|
||||
gl843::gl843_set_xpa_motor_power(&dev, local_reg, false);
|
||||
dev.cmd_set->set_motor_mode(dev, local_reg, MotorMode::PRIMARY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#define BACKEND_GENESYS_GL124_H
|
||||
|
||||
#include "genesys.h"
|
||||
#include "command_set.h"
|
||||
#include "command_set_common.h"
|
||||
|
||||
namespace genesys {
|
||||
namespace gl124 {
|
||||
|
@ -112,7 +112,7 @@ static Memory_layout layouts[]={
|
|||
static void gl124_send_slope_table(Genesys_Device* dev, int table_nr,
|
||||
const std::vector<uint16_t>& slope_table, int steps);
|
||||
|
||||
class CommandSetGl124 : public CommandSet
|
||||
class CommandSetGl124 : public CommandSetCommon
|
||||
{
|
||||
public:
|
||||
~CommandSetGl124() override = default;
|
||||
|
|
|
@ -1473,7 +1473,7 @@ void CommandSetGl646::move_back_home(Genesys_Device* dev, bool wait_until_home)
|
|||
|
||||
if (!i) /* the loop counted down to 0, scanner still is busy */
|
||||
{
|
||||
dev->set_head_pos_unknown();
|
||||
dev->set_head_pos_unknown(ScanHeadId::PRIMARY | ScanHeadId::SECONDARY);
|
||||
throw SaneException(SANE_STATUS_DEVICE_BUSY, "motor is still on: device busy");
|
||||
}
|
||||
|
||||
|
@ -1567,7 +1567,7 @@ void CommandSetGl646::move_back_home(Genesys_Device* dev, bool wait_until_home)
|
|||
// stop the motor
|
||||
catch_all_exceptions(__func__, [&](){ gl646_stop_motor (dev); });
|
||||
catch_all_exceptions(__func__, [&](){ end_scan_impl(dev, &dev->reg, true, false); });
|
||||
dev->set_head_pos_unknown();
|
||||
dev->set_head_pos_unknown(ScanHeadId::PRIMARY | ScanHeadId::SECONDARY);
|
||||
throw SaneException(SANE_STATUS_IO_ERROR, "timeout while waiting for scanhead to go home");
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#define BACKEND_GENESYS_GL646_H
|
||||
|
||||
#include "genesys.h"
|
||||
#include "command_set.h"
|
||||
#include "command_set_common.h"
|
||||
#include "motor.h"
|
||||
|
||||
namespace genesys {
|
||||
|
@ -436,7 +436,7 @@ static Motor_Master motor_master[] = {
|
|||
MotorSlope::create_from_steps(2000, 300, 255), 146}, /* 5500 guessed */
|
||||
};
|
||||
|
||||
class CommandSetGl646 : public CommandSet
|
||||
class CommandSetGl646 : public CommandSetCommon
|
||||
{
|
||||
public:
|
||||
~CommandSetGl646() override = default;
|
||||
|
|
|
@ -2180,7 +2180,7 @@ static void gl841_feed(Genesys_Device* dev, int steps)
|
|||
/* when we come here then the scanner needed too much time for this, so we better stop the motor */
|
||||
gl841_stop_action (dev);
|
||||
|
||||
dev->set_head_pos_unknown();
|
||||
dev->set_head_pos_unknown(ScanHeadId::PRIMARY);
|
||||
|
||||
throw SaneException(SANE_STATUS_IO_ERROR, "timeout while waiting for scanhead to go home");
|
||||
}
|
||||
|
@ -2276,7 +2276,7 @@ void CommandSetGl841::move_back_home(Genesys_Device* dev, bool wait_until_home)
|
|||
// when we come here then the scanner needed too much time for this, so we better stop
|
||||
// the motor
|
||||
catch_all_exceptions(__func__, [&](){ gl841_stop_action(dev); });
|
||||
dev->set_head_pos_unknown();
|
||||
dev->set_head_pos_unknown(ScanHeadId::PRIMARY);
|
||||
throw SaneException(SANE_STATUS_IO_ERROR, "timeout while waiting for scanhead to go home");
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
*/
|
||||
|
||||
#include "genesys.h"
|
||||
#include "command_set.h"
|
||||
#include "command_set_common.h"
|
||||
|
||||
#ifndef BACKEND_GENESYS_GL841_H
|
||||
#define BACKEND_GENESYS_GL841_H
|
||||
|
@ -50,7 +50,7 @@
|
|||
namespace genesys {
|
||||
namespace gl841 {
|
||||
|
||||
class CommandSetGl841 : public CommandSet
|
||||
class CommandSetGl841 : public CommandSetCommon
|
||||
{
|
||||
public:
|
||||
~CommandSetGl841() override = default;
|
||||
|
|
|
@ -1360,194 +1360,6 @@ void CommandSetGl843::detect_document_end(Genesys_Device* dev) const
|
|||
}
|
||||
}
|
||||
|
||||
// enables or disables XPA slider motor
|
||||
void gl843_set_xpa_motor_power(Genesys_Device* dev, Genesys_Register_Set& regs, bool set)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
uint8_t val;
|
||||
|
||||
if (dev->model->model_id == ModelId::CANON_8400F) {
|
||||
|
||||
if (set) {
|
||||
val = dev->interface->read_register(0x6c);
|
||||
val &= ~(REG_0x6C_GPIO16 | REG_0x6C_GPIO13);
|
||||
if (dev->session.output_resolution >= 2400) {
|
||||
val &= ~REG_0x6C_GPIO10;
|
||||
}
|
||||
dev->interface->write_register(0x6c, val);
|
||||
|
||||
val = dev->interface->read_register(0xa9);
|
||||
val |= REG_0xA9_GPO30;
|
||||
val &= ~REG_0xA9_GPO29;
|
||||
dev->interface->write_register(0xa9, val);
|
||||
} else {
|
||||
val = dev->interface->read_register(0x6c);
|
||||
val |= REG_0x6C_GPIO16 | REG_0x6C_GPIO13;
|
||||
dev->interface->write_register(0x6c, val);
|
||||
|
||||
val = dev->interface->read_register(0xa9);
|
||||
val &= ~REG_0xA9_GPO30;
|
||||
val |= REG_0xA9_GPO29;
|
||||
dev->interface->write_register(0xa9, val);
|
||||
}
|
||||
} else if (dev->model->model_id == ModelId::CANON_8600F) {
|
||||
if (set) {
|
||||
val = dev->interface->read_register(REG_0x6C);
|
||||
val &= ~REG_0x6C_GPIO14;
|
||||
if (dev->session.output_resolution >= 2400) {
|
||||
val |= REG_0x6C_GPIO10;
|
||||
}
|
||||
dev->interface->write_register(REG_0x6C, val);
|
||||
|
||||
val = dev->interface->read_register(REG_0xA6);
|
||||
val |= REG_0xA6_GPIO17;
|
||||
val &= ~REG_0xA6_GPIO23;
|
||||
dev->interface->write_register(REG_0xA6, val);
|
||||
} else {
|
||||
val = dev->interface->read_register(REG_0x6C);
|
||||
val |= REG_0x6C_GPIO14;
|
||||
val &= ~REG_0x6C_GPIO10;
|
||||
dev->interface->write_register(REG_0x6C, val);
|
||||
|
||||
val = dev->interface->read_register(REG_0xA6);
|
||||
val &= ~REG_0xA6_GPIO17;
|
||||
val &= ~REG_0xA6_GPIO23;
|
||||
dev->interface->write_register(REG_0xA6, val);
|
||||
}
|
||||
} else if (dev->model->model_id == ModelId::HP_SCANJET_G4050) {
|
||||
if (set) {
|
||||
// set MULTFILM et GPOADF
|
||||
val = dev->interface->read_register(REG_0x6B);
|
||||
val |=REG_0x6B_MULTFILM|REG_0x6B_GPOADF;
|
||||
dev->interface->write_register(REG_0x6B, val);
|
||||
|
||||
val = dev->interface->read_register(REG_0x6C);
|
||||
val &= ~REG_0x6C_GPIO15;
|
||||
dev->interface->write_register(REG_0x6C, val);
|
||||
|
||||
/* Motor power ? No move at all without this one */
|
||||
val = dev->interface->read_register(REG_0xA6);
|
||||
val |= REG_0xA6_GPIO20;
|
||||
dev->interface->write_register(REG_0xA6, val);
|
||||
|
||||
val = dev->interface->read_register(REG_0xA8);
|
||||
val &= ~REG_0xA8_GPO27;
|
||||
dev->interface->write_register(REG_0xA8, val);
|
||||
|
||||
val = dev->interface->read_register(REG_0xA9);
|
||||
val |= REG_0xA9_GPO32|REG_0xA9_GPO31;
|
||||
dev->interface->write_register(REG_0xA9, val);
|
||||
} else {
|
||||
// unset GPOADF
|
||||
val = dev->interface->read_register(REG_0x6B);
|
||||
val &= ~REG_0x6B_GPOADF;
|
||||
dev->interface->write_register(REG_0x6B, val);
|
||||
|
||||
val = dev->interface->read_register(REG_0xA8);
|
||||
val |= REG_0xA8_GPO27;
|
||||
dev->interface->write_register(REG_0xA8, val);
|
||||
|
||||
val = dev->interface->read_register(REG_0xA9);
|
||||
val &= ~REG_0xA9_GPO31;
|
||||
dev->interface->write_register(REG_0xA9, val);
|
||||
}
|
||||
}
|
||||
regs.state.is_xpa_motor_on = set;
|
||||
}
|
||||
|
||||
|
||||
/** @brief light XPA lamp
|
||||
* toggle gpios to switch off regular lamp and light on the
|
||||
* XPA light
|
||||
* @param dev device to set up
|
||||
*/
|
||||
static void gl843_set_xpa_lamp_power(Genesys_Device* dev, bool set)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
|
||||
struct LampSettings {
|
||||
ModelId model_id;
|
||||
ScanMethod scan_method;
|
||||
GenesysRegisterSettingSet regs_on;
|
||||
GenesysRegisterSettingSet regs_off;
|
||||
};
|
||||
|
||||
// FIXME: BUG: we're not clearing the registers to the previous state when returning back when
|
||||
// turning off the lamp
|
||||
LampSettings settings[] = {
|
||||
{ ModelId::CANON_8400F, ScanMethod::TRANSPARENCY, {
|
||||
{ 0xa6, 0x34, 0xf4 },
|
||||
}, {
|
||||
{ 0xa6, 0x40, 0x70 },
|
||||
}
|
||||
},
|
||||
{ ModelId::CANON_8400F, ScanMethod::TRANSPARENCY_INFRARED, {
|
||||
{ 0x6c, 0x40, 0x40 },
|
||||
{ 0xa6, 0x01, 0xff },
|
||||
}, {
|
||||
{ 0x6c, 0x00, 0x40 },
|
||||
{ 0xa6, 0x00, 0xff },
|
||||
}
|
||||
},
|
||||
{ ModelId::CANON_8600F, ScanMethod::TRANSPARENCY, {
|
||||
{ 0xa6, 0x34, 0xf4 },
|
||||
{ 0xa7, 0xe0, 0xe0 },
|
||||
}, {
|
||||
{ 0xa6, 0x40, 0x70 },
|
||||
}
|
||||
},
|
||||
{ ModelId::CANON_8600F, ScanMethod::TRANSPARENCY_INFRARED, {
|
||||
{ 0xa6, 0x00, 0xc0 },
|
||||
{ 0xa7, 0xe0, 0xe0 },
|
||||
{ 0x6c, 0x80, 0x80 },
|
||||
}, {
|
||||
{ 0xa6, 0x00, 0xc0 },
|
||||
{ 0x6c, 0x00, 0x80 },
|
||||
}
|
||||
},
|
||||
{ ModelId::PLUSTEK_OPTICFILM_7200I, ScanMethod::TRANSPARENCY, {
|
||||
}, {
|
||||
{ 0xa6, 0x40, 0x70 }, // BUG: remove this cleanup write, it was enabled by accident
|
||||
}
|
||||
},
|
||||
{ ModelId::PLUSTEK_OPTICFILM_7200I, ScanMethod::TRANSPARENCY_INFRARED, {
|
||||
{ 0xa8, 0x07, 0x07 },
|
||||
}, {
|
||||
{ 0xa8, 0x00, 0x07 },
|
||||
}
|
||||
},
|
||||
{ ModelId::PLUSTEK_OPTICFILM_7300, ScanMethod::TRANSPARENCY, {}, {} },
|
||||
{ ModelId::PLUSTEK_OPTICFILM_7500I, ScanMethod::TRANSPARENCY, {}, {} },
|
||||
{ ModelId::PLUSTEK_OPTICFILM_7500I, ScanMethod::TRANSPARENCY_INFRARED, {
|
||||
{ 0xa8, 0x07, 0x07 },
|
||||
}, {
|
||||
{ 0xa8, 0x00, 0x07 },
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
for (const auto& setting : settings) {
|
||||
if (setting.model_id == dev->model->model_id &&
|
||||
setting.scan_method == dev->settings.scan_method)
|
||||
{
|
||||
apply_reg_settings_to_device(*dev, set ? setting.regs_on : setting.regs_off);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// BUG: we're currently calling the function in shut down path of regular lamp
|
||||
if (set) {
|
||||
throw SaneException("Unexpected code path entered");
|
||||
}
|
||||
|
||||
GenesysRegisterSettingSet regs = {
|
||||
{ 0xa6, 0x40, 0x70 },
|
||||
};
|
||||
apply_reg_settings_to_device(*dev, regs);
|
||||
// TODO: throw exception when we're only calling this function in error return path
|
||||
// throw SaneException("Could not find XPA lamp settings");
|
||||
}
|
||||
|
||||
// Send the low-level scan command
|
||||
void CommandSetGl843::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sensor,
|
||||
Genesys_Register_Set* reg, bool start_motor) const
|
||||
|
@ -1577,11 +1389,11 @@ void CommandSetGl843::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens
|
|||
}
|
||||
|
||||
if (reg->state.is_xpa_on && reg->state.is_lamp_on) {
|
||||
gl843_set_xpa_lamp_power(dev, true);
|
||||
dev->cmd_set->set_xpa_lamp_power(*dev, true);
|
||||
}
|
||||
|
||||
if (reg->state.is_xpa_on) {
|
||||
gl843_set_xpa_motor_power(dev, *reg, true);
|
||||
dev->cmd_set->set_motor_mode(*dev, *reg, MotorMode::PRIMARY_AND_SECONDARY);
|
||||
}
|
||||
|
||||
// blinking led
|
||||
|
@ -1590,17 +1402,17 @@ void CommandSetGl843::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens
|
|||
case GpioId::CANON_8400F:
|
||||
case GpioId::CANON_8600F:
|
||||
if (reg->state.is_xpa_on && reg->state.is_lamp_on) {
|
||||
gl843_set_xpa_lamp_power(dev, true);
|
||||
dev->cmd_set->set_xpa_lamp_power(*dev, true);
|
||||
}
|
||||
if (reg->state.is_xpa_on) {
|
||||
gl843_set_xpa_motor_power(dev, *reg, true);
|
||||
dev->cmd_set->set_motor_mode(*dev, *reg, MotorMode::PRIMARY_AND_SECONDARY);
|
||||
}
|
||||
break;
|
||||
case GpioId::PLUSTEK_OPTICFILM_7200I:
|
||||
case GpioId::PLUSTEK_OPTICFILM_7300:
|
||||
case GpioId::PLUSTEK_OPTICFILM_7500I: {
|
||||
if (reg->state.is_xpa_on && reg->state.is_lamp_on) {
|
||||
gl843_set_xpa_lamp_power(dev, true);
|
||||
dev->cmd_set->set_xpa_lamp_power(*dev, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1619,11 +1431,21 @@ void CommandSetGl843::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens
|
|||
|
||||
scanner_start_action(*dev, start_motor);
|
||||
|
||||
if (reg->state.is_motor_on) {
|
||||
dev->advance_head_pos_by_session(ScanHeadId::PRIMARY);
|
||||
}
|
||||
if (reg->state.is_xpa_motor_on) {
|
||||
dev->advance_head_pos_by_session(ScanHeadId::SECONDARY);
|
||||
switch (reg->state.motor_mode) {
|
||||
case MotorMode::PRIMARY: {
|
||||
if (reg->state.is_motor_on) {
|
||||
dev->advance_head_pos_by_session(ScanHeadId::PRIMARY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MotorMode::PRIMARY_AND_SECONDARY: {
|
||||
if (reg->state.is_motor_on) {
|
||||
dev->advance_head_pos_by_session(ScanHeadId::PRIMARY);
|
||||
}
|
||||
// BUG: we should advance secondary head only if motor was on
|
||||
dev->advance_head_pos_by_session(ScanHeadId::SECONDARY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1640,7 +1462,7 @@ void CommandSetGl843::end_scan(Genesys_Device* dev, Genesys_Register_Set* reg,
|
|||
// turn off XPA lamp if needed
|
||||
// BUG: the if condition below probably shouldn't be enabled when XPA is off
|
||||
if (reg->state.is_xpa_on || reg->state.is_lamp_on) {
|
||||
gl843_set_xpa_lamp_power(dev, false);
|
||||
dev->cmd_set->set_xpa_lamp_power(*dev, false);
|
||||
}
|
||||
|
||||
if (!dev->model->is_sheetfed) {
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
*/
|
||||
|
||||
#include "genesys.h"
|
||||
#include "command_set.h"
|
||||
#include "command_set_common.h"
|
||||
|
||||
#ifndef BACKEND_GENESYS_GL843_H
|
||||
#define BACKEND_GENESYS_GL843_H
|
||||
|
@ -50,7 +50,7 @@
|
|||
namespace genesys {
|
||||
namespace gl843 {
|
||||
|
||||
class CommandSetGl843 : public CommandSet
|
||||
class CommandSetGl843 : public CommandSetCommon
|
||||
{
|
||||
public:
|
||||
~CommandSetGl843() override = default;
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
*/
|
||||
|
||||
#include "genesys.h"
|
||||
#include "command_set.h"
|
||||
#include "command_set_common.h"
|
||||
|
||||
#ifndef BACKEND_GENESYS_GL846_H
|
||||
#define BACKEND_GENESYS_GL846_H
|
||||
|
@ -125,7 +125,7 @@ static Memory_layout layouts[]={
|
|||
{ nullptr, 0, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} }
|
||||
};
|
||||
|
||||
class CommandSetGl846 : public CommandSet
|
||||
class CommandSetGl846 : public CommandSetCommon
|
||||
{
|
||||
public:
|
||||
~CommandSetGl846() override = default;
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#define BACKEND_GENESYS_GL847_H
|
||||
|
||||
#include "genesys.h"
|
||||
#include "command_set.h"
|
||||
#include "command_set_common.h"
|
||||
|
||||
namespace genesys {
|
||||
namespace gl847 {
|
||||
|
@ -113,7 +113,7 @@ static Memory_layout layouts[]={
|
|||
}
|
||||
};
|
||||
|
||||
class CommandSetGl847 : public CommandSet
|
||||
class CommandSetGl847 : public CommandSetCommon
|
||||
{
|
||||
public:
|
||||
~CommandSetGl847() override = default;
|
||||
|
|
|
@ -1505,7 +1505,6 @@ void sanei_genesys_asic_init(Genesys_Device* dev, bool /*max_regs*/)
|
|||
|
||||
// Move to home if needed
|
||||
dev->cmd_set->move_back_home(dev, true);
|
||||
dev->set_head_pos_zero(ScanHeadId::PRIMARY);
|
||||
|
||||
// Set powersaving (default = 15 minutes)
|
||||
dev->cmd_set->set_powersaving(dev, 15);
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#ifndef BACKEND_GENESYS_REGISTER_H
|
||||
#define BACKEND_GENESYS_REGISTER_H
|
||||
|
||||
#include "enums.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -76,7 +77,7 @@ struct GenesysRegisterSetState
|
|||
bool is_lamp_on = false;
|
||||
bool is_xpa_on = false;
|
||||
bool is_motor_on = false;
|
||||
bool is_xpa_motor_on = false;
|
||||
MotorMode motor_mode = MotorMode::PRIMARY;
|
||||
};
|
||||
|
||||
template<class Value>
|
||||
|
|
Ładowanie…
Reference in New Issue