genesys: Add support for Canon 5600F

merge-requests/244/head
Povilas Kanapickas 2020-05-26 01:51:19 +03:00
rodzic b9e4113ef0
commit 3cca2593fc
13 zmienionych plików z 704 dodań i 152 usunięć

Wyświetl plik

@ -84,6 +84,7 @@ void CommandSetCommon::set_xpa_lamp_power(Genesys_Device& dev, bool set) const
// turning off the lamp // turning off the lamp
LampSettings settings[] = { LampSettings settings[] = {
{ ModelId::CANON_4400F, ScanMethod::TRANSPARENCY, {}, {} }, { ModelId::CANON_4400F, ScanMethod::TRANSPARENCY, {}, {} },
{ ModelId::CANON_5600F, ScanMethod::TRANSPARENCY, {}, {} },
{ ModelId::CANON_8400F, ScanMethod::TRANSPARENCY, { { ModelId::CANON_8400F, ScanMethod::TRANSPARENCY, {
{ 0xa6, 0x34, 0xf4 }, { 0xa6, 0x34, 0xf4 },
}, { }, {

Wyświetl plik

@ -174,6 +174,7 @@ std::ostream& operator<<(std::ostream& out, SensorId id)
switch (id) { switch (id) {
case SensorId::CCD_5345: out << "CCD_5345"; break; case SensorId::CCD_5345: out << "CCD_5345"; break;
case SensorId::CCD_CANON_4400F: out << "CCD_CANON_4400F"; break; case SensorId::CCD_CANON_4400F: out << "CCD_CANON_4400F"; break;
case SensorId::CCD_CANON_5600F: out << "CCD_CANON_5600F"; break;
case SensorId::CCD_CANON_8400F: out << "CCD_CANON_8400F"; break; case SensorId::CCD_CANON_8400F: out << "CCD_CANON_8400F"; break;
case SensorId::CCD_CANON_8600F: out << "CCD_CANON_8600F"; break; case SensorId::CCD_CANON_8600F: out << "CCD_CANON_8600F"; break;
case SensorId::CCD_DP665: out << "CCD_DP665"; break; case SensorId::CCD_DP665: out << "CCD_DP665"; break;
@ -230,6 +231,7 @@ std::ostream& operator<<(std::ostream& out, AdcId id)
case AdcId::CANON_LIDE_200: out << "CANON_LIDE_200"; break; case AdcId::CANON_LIDE_200: out << "CANON_LIDE_200"; break;
case AdcId::CANON_LIDE_700F: out << "CANON_LIDE_700F"; break; case AdcId::CANON_LIDE_700F: out << "CANON_LIDE_700F"; break;
case AdcId::CANON_4400F: out << "CANON_4400F"; break; case AdcId::CANON_4400F: out << "CANON_4400F"; break;
case AdcId::CANON_5600F: out << "CANON_5600F"; break;
case AdcId::CANON_8400F: out << "CANON_8400F"; break; case AdcId::CANON_8400F: out << "CANON_8400F"; break;
case AdcId::CANON_8600F: out << "CANON_8600F"; break; case AdcId::CANON_8600F: out << "CANON_8600F"; break;
case AdcId::G4050: out << "G4050"; break; case AdcId::G4050: out << "G4050"; break;
@ -270,6 +272,7 @@ std::ostream& operator<<(std::ostream& out, GpioId id)
case GpioId::CANON_LIDE_210: out << "CANON_LIDE_210"; break; case GpioId::CANON_LIDE_210: out << "CANON_LIDE_210"; break;
case GpioId::CANON_LIDE_700F: out << "CANON_LIDE_700F"; break; case GpioId::CANON_LIDE_700F: out << "CANON_LIDE_700F"; break;
case GpioId::CANON_4400F: out << "CANON_4400F"; break; case GpioId::CANON_4400F: out << "CANON_4400F"; break;
case GpioId::CANON_5600F: out << "CANON_5600F"; break;
case GpioId::CANON_8400F: out << "CANON_8400F"; break; case GpioId::CANON_8400F: out << "CANON_8400F"; break;
case GpioId::CANON_8600F: out << "CANON_8600F"; break; case GpioId::CANON_8600F: out << "CANON_8600F"; break;
case GpioId::DP665: out << "DP665"; break; case GpioId::DP665: out << "DP665"; break;
@ -313,6 +316,7 @@ std::ostream& operator<<(std::ostream& out, MotorId id)
case MotorId::CANON_LIDE_700: out << "CANON_LIDE_700"; break; case MotorId::CANON_LIDE_700: out << "CANON_LIDE_700"; break;
case MotorId::CANON_LIDE_80: out << "CANON_LIDE_80"; break; case MotorId::CANON_LIDE_80: out << "CANON_LIDE_80"; break;
case MotorId::CANON_4400F: out << "CANON_4400F"; break; case MotorId::CANON_4400F: out << "CANON_4400F"; break;
case MotorId::CANON_5600F: out << "CANON_5600F"; break;
case MotorId::CANON_8400F: out << "CANON_8400F"; break; case MotorId::CANON_8400F: out << "CANON_8400F"; break;
case MotorId::CANON_8600F: out << "CANON_8600F"; break; case MotorId::CANON_8600F: out << "CANON_8600F"; break;
case MotorId::DP665: out << "DP665"; break; case MotorId::DP665: out << "DP665"; break;

Wyświetl plik

@ -245,6 +245,7 @@ enum class SensorId : unsigned
UNKNOWN = 0, UNKNOWN = 0,
CCD_5345, CCD_5345,
CCD_CANON_4400F, CCD_CANON_4400F,
CCD_CANON_5600F,
CCD_CANON_8400F, CCD_CANON_8400F,
CCD_CANON_8600F, CCD_CANON_8600F,
CCD_DP665, CCD_DP665,
@ -312,6 +313,7 @@ enum class AdcId : unsigned
CANON_LIDE_200, CANON_LIDE_200,
CANON_LIDE_700F, CANON_LIDE_700F,
CANON_4400F, CANON_4400F,
CANON_5600F,
CANON_8400F, CANON_8400F,
CANON_8600F, CANON_8600F,
G4050, G4050,
@ -362,6 +364,7 @@ enum class GpioId : unsigned
CANON_LIDE_210, CANON_LIDE_210,
CANON_LIDE_700F, CANON_LIDE_700F,
CANON_4400F, CANON_4400F,
CANON_5600F,
CANON_8400F, CANON_8400F,
CANON_8600F, CANON_8600F,
DP665, DP665,
@ -404,6 +407,7 @@ enum class MotorId : unsigned
CANON_LIDE_700, CANON_LIDE_700,
CANON_LIDE_80, CANON_LIDE_80,
CANON_4400F, CANON_4400F,
CANON_5600F,
CANON_8400F, CANON_8400F,
CANON_8600F, CANON_8600F,
DP665, DP665,

Wyświetl plik

@ -1491,6 +1491,16 @@ void scanner_offset_calibration(Genesys_Device& dev, const Genesys_Sensor& senso
} }
} }
if (dev.model->model_id == ModelId::CANON_5600F) {
// FIXME: use same approach as for GL843 scanners
lines = 8;
}
if (dev.model->asic_type == AsicType::GL847) {
calib_sensor = &sanei_genesys_find_sensor(&dev, resolution, channels,
dev.settings.scan_method);
}
ScanFlag flags = ScanFlag::DISABLE_SHADING | ScanFlag flags = ScanFlag::DISABLE_SHADING |
ScanFlag::DISABLE_GAMMA | ScanFlag::DISABLE_GAMMA |
ScanFlag::SINGLE_LINE | ScanFlag::SINGLE_LINE |
@ -1562,6 +1572,10 @@ void scanner_offset_calibration(Genesys_Device& dev, const Genesys_Sensor& senso
scanner_stop_action_no_move(dev, regs); scanner_stop_action_no_move(dev, regs);
} else { } else {
first_line = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes); first_line = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes);
if (dev.model->model_id == ModelId::CANON_5600F) {
scanner_stop_action_no_move(dev, regs);
}
} }
if (dbg_log_image_data()) { if (dbg_log_image_data()) {
@ -1598,6 +1612,10 @@ void scanner_offset_calibration(Genesys_Device& dev, const Genesys_Sensor& senso
scanner_stop_action_no_move(dev, regs); scanner_stop_action_no_move(dev, regs);
} else { } else {
second_line = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes); second_line = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes);
if (dev.model->model_id == ModelId::CANON_5600F) {
scanner_stop_action_no_move(dev, regs);
}
} }
for (unsigned ch = 0; ch < 3; ch++){ for (unsigned ch = 0; ch < 3; ch++){
@ -1638,6 +1656,10 @@ void scanner_offset_calibration(Genesys_Device& dev, const Genesys_Sensor& senso
scanner_stop_action_no_move(dev, regs); scanner_stop_action_no_move(dev, regs);
} else { } else {
second_line = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes); second_line = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes);
if (dev.model->model_id == ModelId::CANON_5600F) {
scanner_stop_action_no_move(dev, regs);
}
} }
if (dbg_log_image_data()) { if (dbg_log_image_data()) {
@ -1782,7 +1804,8 @@ void scanner_coarse_gain_calibration(Genesys_Device& dev, const Genesys_Sensor&
const Genesys_Sensor* calib_sensor = &sensor; const Genesys_Sensor* calib_sensor = &sensor;
if (dev.model->asic_type == AsicType::GL841 || if (dev.model->asic_type == AsicType::GL841 ||
dev.model->asic_type == AsicType::GL842 || dev.model->asic_type == AsicType::GL842 ||
dev.model->asic_type == AsicType::GL843) dev.model->asic_type == AsicType::GL843 ||
dev.model->asic_type == AsicType::GL847)
{ {
calib_sensor = &sanei_genesys_find_sensor(&dev, resolution, channels, calib_sensor = &sanei_genesys_find_sensor(&dev, resolution, channels,
dev.settings.scan_method); dev.settings.scan_method);
@ -1930,6 +1953,9 @@ void scanner_coarse_gain_calibration(Genesys_Device& dev, const Genesys_Sensor&
DBG(DBG_error0, "****************************************\n"); DBG(DBG_error0, "****************************************\n");
throw SaneException(SANE_STATUS_JAMMED, "scanning head is locked"); throw SaneException(SANE_STATUS_JAMMED, "scanning head is locked");
} }
dbg.vlog(DBG_info, "gain=(%d, %d, %d)", dev.frontend.get_gain(0), dev.frontend.get_gain(1),
dev.frontend.get_gain(2));
} }
if (dev.model->is_cis) { if (dev.model->is_cis) {
@ -1942,10 +1968,8 @@ void scanner_coarse_gain_calibration(Genesys_Device& dev, const Genesys_Sensor&
dev.frontend.set_gain(2, min_gain); dev.frontend.set_gain(2, min_gain);
} }
DBG(DBG_info, "%s: gain=(%d,%d,%d)\n", __func__, dbg.vlog(DBG_info, "final gain=(%d, %d, %d)", dev.frontend.get_gain(0),
dev.frontend.get_gain(0), dev.frontend.get_gain(1), dev.frontend.get_gain(2));
dev.frontend.get_gain(1),
dev.frontend.get_gain(2));
scanner_stop_action(dev); scanner_stop_action(dev);
@ -2326,10 +2350,12 @@ static void genesys_shading_calibration_impl(Genesys_Device* dev, const Genesys_
uint32_t pixels_per_line; uint32_t pixels_per_line;
if (dev->model->asic_type == AsicType::GL842 || if (dev->model->asic_type == AsicType::GL842 ||
dev->model->asic_type == AsicType::GL843) dev->model->asic_type == AsicType::GL843 ||
dev->model->model_id == ModelId::CANON_5600F)
{ {
pixels_per_line = dev->calib_session.output_pixels; pixels_per_line = dev->calib_session.output_pixels;
} else { } else {
// BUG: this selects incorrect pixel number
pixels_per_line = dev->calib_session.params.pixels; pixels_per_line = dev->calib_session.params.pixels;
} }
unsigned channels = dev->calib_session.params.channels; unsigned channels = dev->calib_session.params.channels;
@ -2354,7 +2380,8 @@ static void genesys_shading_calibration_impl(Genesys_Device* dev, const Genesys_
// FIXME: the current calculation is likely incorrect on non-GL843 implementations, // FIXME: the current calculation is likely incorrect on non-GL843 implementations,
// but this needs checking. Note the extra line when computing size. // but this needs checking. Note the extra line when computing size.
if (dev->model->asic_type == AsicType::GL842 || if (dev->model->asic_type == AsicType::GL842 ||
dev->model->asic_type == AsicType::GL843) dev->model->asic_type == AsicType::GL843 ||
dev->model->model_id == ModelId::CANON_5600F)
{ {
size = dev->calib_session.output_total_bytes_raw; size = dev->calib_session.output_total_bytes_raw;
} else { } else {
@ -2407,6 +2434,12 @@ static void genesys_shading_calibration_impl(Genesys_Device* dev, const Genesys_
} }
} }
if (has_flag(dev->model->flags, ModelFlag::INVERT_PIXEL_DATA)) {
for (std::size_t i = 0; i < size / 2; ++i) {
calibration_data[i] = 0xffff - calibration_data[i];
}
}
std::fill(out_average_data.begin(), std::fill(out_average_data.begin(),
out_average_data.begin() + start_offset * channels, 0); out_average_data.begin() + start_offset * channels, 0);
@ -3489,6 +3522,7 @@ static void genesys_send_shading_coefficient(Genesys_Device* dev, const Genesys_
case SensorId::CIS_CANON_LIDE_120: case SensorId::CIS_CANON_LIDE_120:
case SensorId::CIS_CANON_LIDE_210: case SensorId::CIS_CANON_LIDE_210:
case SensorId::CIS_CANON_LIDE_220: case SensorId::CIS_CANON_LIDE_220:
case SensorId::CCD_CANON_5600F:
/* TODO store this in a data struct so we avoid /* TODO store this in a data struct so we avoid
* growing this switch */ * growing this switch */
switch(dev->model->sensor_id) switch(dev->model->sensor_id)

Wyświetl plik

@ -84,30 +84,49 @@ gl847_init_registers (Genesys_Device * dev)
dev->reg.clear(); dev->reg.clear();
dev->reg.init_reg(0x01, 0x82); dev->reg.init_reg(0x01, 0x82);
if (dev->model->model_id == ModelId::CANON_5600F) {
dev->reg.init_reg(0x01, 0x40);
}
dev->reg.init_reg(0x02, 0x18); dev->reg.init_reg(0x02, 0x18);
dev->reg.init_reg(0x03, 0x50); dev->reg.init_reg(0x03, 0x50);
dev->reg.init_reg(0x04, 0x12); dev->reg.init_reg(0x04, 0x12);
if (dev->model->model_id == ModelId::CANON_5600F) {
dev->reg.init_reg(0x04, 0x20);
}
dev->reg.init_reg(0x05, 0x80); dev->reg.init_reg(0x05, 0x80);
dev->reg.init_reg(0x06, 0x50); // FASTMODE + POWERBIT dev->reg.init_reg(0x06, 0x50); // FASTMODE + POWERBIT
if (dev->model->model_id == ModelId::CANON_5600F) {
dev->reg.init_reg(0x06, 0xf8);
}
dev->reg.init_reg(0x08, 0x10); dev->reg.init_reg(0x08, 0x10);
if (dev->model->model_id == ModelId::CANON_5600F) {
dev->reg.init_reg(0x08, 0x20);
}
dev->reg.init_reg(0x09, 0x01); dev->reg.init_reg(0x09, 0x01);
if (dev->model->model_id == ModelId::CANON_5600F) {
dev->reg.init_reg(0x09, 0x00);
}
dev->reg.init_reg(0x0a, 0x00); dev->reg.init_reg(0x0a, 0x00);
dev->reg.init_reg(0x0b, 0x01); dev->reg.init_reg(0x0b, 0x01);
if (dev->model->model_id == ModelId::CANON_5600F) {
dev->reg.init_reg(0x0b, 0x6b);
}
dev->reg.init_reg(0x0c, 0x02); dev->reg.init_reg(0x0c, 0x02);
if (dev->model->model_id == ModelId::CANON_5600F) {
dev->reg.init_reg(0x0c, 0x00);
}
// LED exposures // LED exposures
dev->reg.init_reg(0x10, 0x00); dev->reg.init_reg(0x10, 0x00); // exposure, overwritten in scanner_setup_sensor() below
dev->reg.init_reg(0x11, 0x00); dev->reg.init_reg(0x11, 0x00); // exposure, overwritten in scanner_setup_sensor() below
dev->reg.init_reg(0x12, 0x00); dev->reg.init_reg(0x12, 0x00); // exposure, overwritten in scanner_setup_sensor() below
dev->reg.init_reg(0x13, 0x00); dev->reg.init_reg(0x13, 0x00); // exposure, overwritten in scanner_setup_sensor() below
dev->reg.init_reg(0x14, 0x00); dev->reg.init_reg(0x14, 0x00); // exposure, overwritten in scanner_setup_sensor() below
dev->reg.init_reg(0x15, 0x00); dev->reg.init_reg(0x15, 0x00); // exposure, overwritten in scanner_setup_sensor() below
dev->reg.init_reg(0x16, 0x10); // SENSOR_DEF dev->reg.init_reg(0x16, 0x10); // SENSOR_DEF
dev->reg.init_reg(0x17, 0x08); // SENSOR_DEF dev->reg.init_reg(0x17, 0x08); // SENSOR_DEF
dev->reg.init_reg(0x18, 0x00); // SENSOR_DEF dev->reg.init_reg(0x18, 0x00); // SENSOR_DEF
// EXPDMY
dev->reg.init_reg(0x19, 0x50); // SENSOR_DEF dev->reg.init_reg(0x19, 0x50); // SENSOR_DEF
dev->reg.init_reg(0x1a, 0x34); // SENSOR_DEF dev->reg.init_reg(0x1a, 0x34); // SENSOR_DEF
@ -115,32 +134,40 @@ gl847_init_registers (Genesys_Device * dev)
dev->reg.init_reg(0x1c, 0x02); // SENSOR_DEF dev->reg.init_reg(0x1c, 0x02); // SENSOR_DEF
dev->reg.init_reg(0x1d, 0x04); // SENSOR_DEF dev->reg.init_reg(0x1d, 0x04); // SENSOR_DEF
dev->reg.init_reg(0x1e, 0x10); dev->reg.init_reg(0x1e, 0x10);
if (dev->model->model_id == ModelId::CANON_5600F) {
dev->reg.init_reg(0x1e, 0xf0);
}
dev->reg.init_reg(0x1f, 0x04); dev->reg.init_reg(0x1f, 0x04);
dev->reg.init_reg(0x20, 0x02); dev->reg.init_reg(0x20, 0x02); // BUFSEL: buffer full condition
dev->reg.init_reg(0x21, 0x10); dev->reg.init_reg(0x21, 0x10); // STEPNO: set during motor setup
dev->reg.init_reg(0x22, 0x7f); dev->reg.init_reg(0x22, 0x7f); // FWDSTEP: set during motor setup
dev->reg.init_reg(0x23, 0x7f); dev->reg.init_reg(0x23, 0x7f); // BWDSTEP: set during motor setup
dev->reg.init_reg(0x24, 0x10); dev->reg.init_reg(0x24, 0x10); // FASTNO: set during motor setup
dev->reg.init_reg(0x25, 0x00); dev->reg.init_reg(0x25, 0x00); // LINCNT: set during motor setup
dev->reg.init_reg(0x26, 0x00); dev->reg.init_reg(0x26, 0x00); // LINCNT: set during motor setup
dev->reg.init_reg(0x27, 0x00); dev->reg.init_reg(0x27, 0x00); // LINCNT: set during motor setup
dev->reg.init_reg(0x2c, 0x09);
dev->reg.init_reg(0x2d, 0x60); dev->reg.init_reg(0x2c, 0x09); // DPISET: set during sensor setup
dev->reg.init_reg(0x2e, 0x80); dev->reg.init_reg(0x2d, 0x60); // DPISET: set during sensor setup
dev->reg.init_reg(0x2f, 0x80);
dev->reg.init_reg(0x30, 0x00); dev->reg.init_reg(0x2e, 0x80); // BWHI: black/white low threshdold
dev->reg.init_reg(0x31, 0x10); dev->reg.init_reg(0x2f, 0x80); // BWLOW: black/white low threshold
dev->reg.init_reg(0x32, 0x15);
dev->reg.init_reg(0x33, 0x0e); dev->reg.init_reg(0x30, 0x00); // STRPIXEL: set during sensor setup
dev->reg.init_reg(0x34, 0x40); dev->reg.init_reg(0x31, 0x10); // STRPIXEL: set during sensor setup
dev->reg.init_reg(0x35, 0x00); dev->reg.init_reg(0x32, 0x15); // ENDPIXEL: set during sensor setup
dev->reg.init_reg(0x36, 0x2a); dev->reg.init_reg(0x33, 0x0e); // ENDPIXEL: set during sensor setup
dev->reg.init_reg(0x37, 0x30);
dev->reg.init_reg(0x38, 0x2a); dev->reg.init_reg(0x34, 0x40); // DUMMY: SENSOR_DEF
dev->reg.init_reg(0x39, 0xf8); dev->reg.init_reg(0x35, 0x00); // MAXWD: set during scan setup
dev->reg.init_reg(0x3d, 0x00); dev->reg.init_reg(0x36, 0x2a); // MAXWD: set during scan setup
dev->reg.init_reg(0x3e, 0x00); dev->reg.init_reg(0x37, 0x30); // MAXWD: set during scan setup
dev->reg.init_reg(0x3f, 0x00); dev->reg.init_reg(0x38, 0x2a); // LPERIOD: SENSOR_DEF
dev->reg.init_reg(0x39, 0xf8); // LPERIOD: SENSOR_DEF
dev->reg.init_reg(0x3d, 0x00); // FEEDL: set during motor setup
dev->reg.init_reg(0x3e, 0x00); // FEEDL: set during motor setup
dev->reg.init_reg(0x3f, 0x00); // FEEDL: set during motor setup
dev->reg.init_reg(0x52, 0x03); // SENSOR_DEF dev->reg.init_reg(0x52, 0x03); // SENSOR_DEF
dev->reg.init_reg(0x53, 0x07); // SENSOR_DEF dev->reg.init_reg(0x53, 0x07); // SENSOR_DEF
dev->reg.init_reg(0x54, 0x00); // SENSOR_DEF dev->reg.init_reg(0x54, 0x00); // SENSOR_DEF
@ -150,30 +177,27 @@ gl847_init_registers (Genesys_Device * dev)
dev->reg.init_reg(0x58, 0x2a); // SENSOR_DEF dev->reg.init_reg(0x58, 0x2a); // SENSOR_DEF
dev->reg.init_reg(0x59, 0xe1); // SENSOR_DEF dev->reg.init_reg(0x59, 0xe1); // SENSOR_DEF
dev->reg.init_reg(0x5a, 0x55); // SENSOR_DEF dev->reg.init_reg(0x5a, 0x55); // SENSOR_DEF
dev->reg.init_reg(0x5e, 0x41);
dev->reg.init_reg(0x5f, 0x40);
dev->reg.init_reg(0x60, 0x00);
dev->reg.init_reg(0x61, 0x21);
dev->reg.init_reg(0x62, 0x40);
dev->reg.init_reg(0x63, 0x00);
dev->reg.init_reg(0x64, 0x21);
dev->reg.init_reg(0x65, 0x40);
dev->reg.init_reg(0x67, 0x80);
dev->reg.init_reg(0x68, 0x80);
dev->reg.init_reg(0x69, 0x20);
dev->reg.init_reg(0x6a, 0x20);
// CK1MAP dev->reg.init_reg(0x5e, 0x41); // DECSEL, STOPTIM
dev->reg.init_reg(0x5f, 0x40); // FMOVDEC: set during motor setup
dev->reg.init_reg(0x60, 0x00); // Z1MOD: overwritten during motor setup
dev->reg.init_reg(0x61, 0x21); // Z1MOD: overwritten during motor setup
dev->reg.init_reg(0x62, 0x40); // Z1MOD: overwritten during motor setup
dev->reg.init_reg(0x63, 0x00); // Z2MOD: overwritten during motor setup
dev->reg.init_reg(0x64, 0x21); // Z2MOD: overwritten during motor setup
dev->reg.init_reg(0x65, 0x40); // Z2MOD: overwritten during motor setup
dev->reg.init_reg(0x67, 0x80); // STEPSEL, MTRPWM: overwritten during motor setup
dev->reg.init_reg(0x68, 0x80); // FSTPSEL, FASTPWM: overwritten during motor setup
dev->reg.init_reg(0x69, 0x20); // FSHDEC: overwritten during motor setup
dev->reg.init_reg(0x6a, 0x20); // FMOVNO: overwritten during motor setup
dev->reg.init_reg(0x74, 0x00); // SENSOR_DEF dev->reg.init_reg(0x74, 0x00); // SENSOR_DEF
dev->reg.init_reg(0x75, 0x00); // SENSOR_DEF dev->reg.init_reg(0x75, 0x00); // SENSOR_DEF
dev->reg.init_reg(0x76, 0x3c); // SENSOR_DEF dev->reg.init_reg(0x76, 0x3c); // SENSOR_DEF
// CK3MAP
dev->reg.init_reg(0x77, 0x00); // SENSOR_DEF dev->reg.init_reg(0x77, 0x00); // SENSOR_DEF
dev->reg.init_reg(0x78, 0x00); // SENSOR_DEF dev->reg.init_reg(0x78, 0x00); // SENSOR_DEF
dev->reg.init_reg(0x79, 0x9f); // SENSOR_DEF dev->reg.init_reg(0x79, 0x9f); // SENSOR_DEF
// CK4MAP
dev->reg.init_reg(0x7a, 0x00); // SENSOR_DEF dev->reg.init_reg(0x7a, 0x00); // SENSOR_DEF
dev->reg.init_reg(0x7b, 0x00); // SENSOR_DEF dev->reg.init_reg(0x7b, 0x00); // SENSOR_DEF
dev->reg.init_reg(0x7c, 0x55); // SENSOR_DEF dev->reg.init_reg(0x7c, 0x55); // SENSOR_DEF
@ -181,11 +205,23 @@ gl847_init_registers (Genesys_Device * dev)
dev->reg.init_reg(0x7d, 0x00); dev->reg.init_reg(0x7d, 0x00);
// NOTE: autoconf is a non working option // NOTE: autoconf is a non working option
dev->reg.init_reg(0x87, 0x02); dev->reg.init_reg(0x87, 0x02); // TODO: move to SENSOR_DEF
dev->reg.init_reg(0x9d, 0x06); dev->reg.init_reg(0x9d, 0x06); // RAMDLY, MOTLAG, CMODE, STEPTIM, IFRS
dev->reg.init_reg(0xa2, 0x0f); dev->reg.init_reg(0xa2, 0x0f); // misc
dev->reg.init_reg(0xbd, 0x18);
dev->reg.init_reg(0xfe, 0x08); if (dev->model->model_id == ModelId::CANON_5600F) {
dev->reg.init_reg(0xab, 0x31);
dev->reg.init_reg(0xbb, 0x00);
dev->reg.init_reg(0xbc, 0x0f);
}
dev->reg.init_reg(0xbd, 0x18); // misc
dev->reg.init_reg(0xfe, 0x08); // misc
if (dev->model->model_id == ModelId::CANON_5600F) {
dev->reg.init_reg(0x9e, 0x00); // sensor reg, but not in SENSOR_DEF
dev->reg.init_reg(0x9f, 0x00); // sensor reg, but not in SENSOR_DEF
dev->reg.init_reg(0xaa, 0x00); // custom data
dev->reg.init_reg(0xff, 0x00);
}
// gamma[0] and gamma[256] values // gamma[0] and gamma[256] values
dev->reg.init_reg(0xbe, 0x00); dev->reg.init_reg(0xbe, 0x00);
@ -213,6 +249,10 @@ gl847_init_registers (Genesys_Device * dev)
const auto& dpihw_sensor = sanei_genesys_find_sensor(dev, sensor.full_resolution, const auto& dpihw_sensor = sanei_genesys_find_sensor(dev, sensor.full_resolution,
3, ScanMethod::FLATBED); 3, ScanMethod::FLATBED);
sanei_genesys_set_dpihw(dev->reg, dpihw_sensor.register_dpihw); sanei_genesys_set_dpihw(dev->reg, dpihw_sensor.register_dpihw);
if (dev->model->model_id == ModelId::CANON_5600F) {
scanner_setup_sensor(*dev, sensor, dev->reg);
}
} }
// Set values of analog frontend // Set values of analog frontend
@ -224,11 +264,9 @@ void CommandSetGl847::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor,
(void) sensor; (void) sensor;
uint8_t val = dev->interface->read_register(REG_0x04); if (dev->model->model_id != ModelId::CANON_5600F) {
uint8_t frontend_type = val & REG_0x04_FESET; // FIXME: remove the following read
dev->interface->read_register(REG_0x04);
if (frontend_type != 0x02) {
throw SaneException("unsupported frontend type %d", frontend_type);
} }
// wait for FE to be ready // wait for FE to be ready
@ -242,14 +280,46 @@ void CommandSetGl847::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor,
dev->frontend = dev->frontend_initial; dev->frontend = dev->frontend_initial;
} }
// reset DAC if (dev->model->model_id != ModelId::CANON_5600F) {
// reset DAC (BUG: this does completely different thing on Analog Devices ADCs)
dev->interface->write_fe_register(0x00, 0x80); dev->interface->write_fe_register(0x00, 0x80);
} else {
if (dev->frontend.layout.type == FrontendType::WOLFSON) {
// reset DAC
dev->interface->write_fe_register(0x04, 0xff);
}
}
for (const auto& reg : dev->frontend.regs) { for (const auto& reg : dev->frontend.regs) {
dev->interface->write_fe_register(reg.address, reg.value); dev->interface->write_fe_register(reg.address, reg.value);
} }
} }
static void gl847_write_motor_phase_table(Genesys_Device& dev, unsigned ydpi)
{
(void) ydpi;
if (dev.model->model_id == ModelId::CANON_5600F) {
std::vector<std::uint8_t> phase_table = {
0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00,
0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00,
0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00,
0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00,
0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00,
0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00,
0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00,
0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12, 0x00,
0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00,
0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00,
0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00,
0x25, 0x00, 0x25, 0x00, 0x25, 0x00, 0x25, 0x00,
0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00,
};
dev.interface->write_ahb(0x01000a00, phase_table.size(), phase_table.data());
}
}
// @brief set up motor related register for scan // @brief set up motor related register for scan
static void gl847_init_motor_regs_scan(Genesys_Device* dev, static void gl847_init_motor_regs_scan(Genesys_Device* dev,
@ -326,6 +396,8 @@ static void gl847_init_motor_regs_scan(Genesys_Device* dev,
scanner_send_slope_table(dev, sensor, FAST_TABLE, fast_table.table); scanner_send_slope_table(dev, sensor, FAST_TABLE, fast_table.table);
scanner_send_slope_table(dev, sensor, HOME_TABLE, fast_table.table); scanner_send_slope_table(dev, sensor, HOME_TABLE, fast_table.table);
gl847_write_motor_phase_table(*dev, scan_yres);
// correct move distance by acceleration and deceleration amounts // correct move distance by acceleration and deceleration amounts
unsigned feedl = feed_steps; unsigned feedl = feed_steps;
unsigned dist = 0; unsigned dist = 0;
@ -441,21 +513,29 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
reg->find_reg(REG_0x01).value |= REG_0x01_SHDAREA; reg->find_reg(REG_0x01).value |= REG_0x01_SHDAREA;
if (has_flag(session.params.flags, ScanFlag::DISABLE_SHADING) || if (has_flag(session.params.flags, ScanFlag::DISABLE_SHADING) ||
has_flag(dev->model->flags, ModelFlag::DISABLE_SHADING_CALIBRATION)) has_flag(dev->model->flags, ModelFlag::DISABLE_SHADING_CALIBRATION) ||
session.use_host_side_calib)
{ {
reg->find_reg(REG_0x01).value &= ~REG_0x01_DVDSET; reg->find_reg(REG_0x01).value &= ~REG_0x01_DVDSET;
} } else {
else
{
reg->find_reg(REG_0x01).value |= REG_0x01_DVDSET; reg->find_reg(REG_0x01).value |= REG_0x01_DVDSET;
} }
reg->find_reg(REG_0x03).value &= ~REG_0x03_AVEENB; reg->find_reg(REG_0x03).value &= ~REG_0x03_AVEENB;
reg->find_reg(REG_0x03).value &= ~REG_0x03_XPASEL;
if (has_flag(session.params.flags, ScanFlag::USE_XPA)) {
reg->find_reg(REG_0x03).value |= REG_0x03_XPASEL;
}
sanei_genesys_set_lamp_power(dev, sensor, *reg, sanei_genesys_set_lamp_power(dev, sensor, *reg,
!has_flag(session.params.flags, ScanFlag::DISABLE_LAMP)); !has_flag(session.params.flags, ScanFlag::DISABLE_LAMP));
reg->state.is_xpa_on = has_flag(session.params.flags, ScanFlag::USE_XPA); reg->state.is_xpa_on = has_flag(session.params.flags, ScanFlag::USE_XPA);
if (has_flag(session.params.flags, ScanFlag::USE_XPA)) {
if (dev->model->model_id == ModelId::CANON_5600F) {
regs_set_exposure(dev->model->asic_type, *reg, sanei_genesys_fixup_exposure({0, 0, 0}));
}
}
// BW threshold // BW threshold
reg->set8(0x2e, 0x7f); reg->set8(0x2e, 0x7f);
reg->set8(0x2f, 0x7f); reg->set8(0x2f, 0x7f);
@ -489,9 +569,13 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
default: default:
break; // should not happen break; // should not happen
} }
} else {
if (dev->model->model_id == ModelId::CANON_5600F) {
reg->find_reg(REG_0x04).value |= 0x20;
} else { } else {
reg->find_reg(REG_0x04).value |= 0x10; // mono reg->find_reg(REG_0x04).value |= 0x10; // mono
} }
}
const auto& dpihw_sensor = sanei_genesys_find_sensor(dev, session.output_resolution, const auto& dpihw_sensor = sanei_genesys_find_sensor(dev, session.output_resolution,
session.params.channels, session.params.channels,
@ -545,7 +629,13 @@ void CommandSetGl847::init_regs_for_scan_session(Genesys_Device* dev, const Gene
int slope_dpi = 0; int slope_dpi = 0;
int dummy = 0; int dummy = 0;
if (dev->model->model_id == ModelId::CANON_LIDE_100 ||
dev->model->model_id == ModelId::CANON_LIDE_200 ||
dev->model->model_id == ModelId::CANON_LIDE_700F ||
dev->model->model_id == ModelId::HP_SCANJET_N6310)
{
dummy = 3 - session.params.channels; dummy = 3 - session.params.channels;
}
/* slope_dpi */ /* slope_dpi */
/* cis color scan is effectively a gray scan with 3 gray lines per color /* cis color scan is effectively a gray scan with 3 gray lines per color
@ -685,11 +775,42 @@ void CommandSetGl847::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens
dev->interface->write_register(REG_0x6C, val); dev->interface->write_register(REG_0x6C, val);
} }
if (dev->model->model_id == ModelId::CANON_5600F) {
switch (dev->session.params.xres) {
case 75:
case 150:
case 300:
scanner_register_rw_bits(*dev, REG_0xA6, 0x04, 0x1c);
break;
case 600:
scanner_register_rw_bits(*dev, REG_0xA6, 0x18, 0x1c);
break;
case 1200:
scanner_register_rw_bits(*dev, REG_0xA6, 0x08, 0x1c);
break;
case 2400:
scanner_register_rw_bits(*dev, REG_0xA6, 0x10, 0x1c);
break;
case 4800:
scanner_register_rw_bits(*dev, REG_0xA6, 0x00, 0x1c);
break;
default:
throw SaneException("Unexpected xres");
}
dev->interface->write_register(0x6c, 0xf0);
dev->interface->write_register(0x6b, 0x87);
dev->interface->write_register(0x6d, 0x5f);
}
if (dev->model->model_id == ModelId::CANON_5600F) {
scanner_clear_scan_and_feed_counts(*dev);
} else {
// FIXME: use scanner_clear_scan_and_feed_counts() // FIXME: use scanner_clear_scan_and_feed_counts()
val = REG_0x0D_CLRLNCNT; val = REG_0x0D_CLRLNCNT;
dev->interface->write_register(REG_0x0D, val); dev->interface->write_register(REG_0x0D, val);
val = REG_0x0D_CLRMCNT; val = REG_0x0D_CLRMCNT;
dev->interface->write_register(REG_0x0D, val); dev->interface->write_register(REG_0x0D, val);
}
val = dev->interface->read_register(REG_0x01); val = dev->interface->read_register(REG_0x01);
val |= REG_0x01_SCAN; val |= REG_0x01_SCAN;
@ -823,6 +944,10 @@ void CommandSetGl847::send_shading_data(Genesys_Device* dev, const Genesys_Senso
/* base addr of data has been written in reg D0-D4 in 4K word, so AHB address /* base addr of data has been written in reg D0-D4 in 4K word, so AHB address
* is 8192*reg value */ * is 8192*reg value */
if (dev->model->model_id == ModelId::CANON_5600F) {
return;
}
/* write actual color channel data */ /* write actual color channel data */
for(i=0;i<3;i++) for(i=0;i<3;i++)
{ {
@ -869,6 +994,13 @@ static void gl847_init_gpio(Genesys_Device* dev)
{ {
DBG_HELPER(dbg); DBG_HELPER(dbg);
if (dev->model->model_id == ModelId::CANON_5600F) {
apply_registers_ordered(dev->gpo.regs, {0xa6, 0xa7, 0x6f, 0x6e},
[&](const GenesysRegisterSetting& reg)
{
dev->interface->write_register(reg.address, reg.value);
});
} else {
std::vector<std::uint16_t> order1 = { 0xa7, 0xa6, 0x6e }; std::vector<std::uint16_t> order1 = { 0xa7, 0xa6, 0x6e };
std::vector<std::uint16_t> order2 = { 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0xa8, 0xa9 }; std::vector<std::uint16_t> order2 = { 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0xa8, 0xa9 };
@ -891,6 +1023,7 @@ static void gl847_init_gpio(Genesys_Device* dev)
} }
dev->interface->write_register(reg.address, reg.value); dev->interface->write_register(reg.address, reg.value);
} }
}
} }
/** /**
@ -900,18 +1033,17 @@ static void gl847_init_memory_layout(Genesys_Device* dev)
{ {
DBG_HELPER(dbg); DBG_HELPER(dbg);
// TODO: move to initial register list // FIXME: move to initial register list
switch (dev->model->model_id) { switch (dev->model->model_id) {
case ModelId::CANON_LIDE_100: case ModelId::CANON_LIDE_100:
case ModelId::CANON_LIDE_200: case ModelId::CANON_LIDE_200:
case ModelId::CANON_5600F:
dev->interface->write_register(REG_0x0B, 0x29); dev->interface->write_register(REG_0x0B, 0x29);
break; break;
case ModelId::CANON_LIDE_700F: case ModelId::CANON_LIDE_700F:
dev->interface->write_register(REG_0x0B, 0x2a); dev->interface->write_register(REG_0x0B, 0x2a);
break; break;
default: default:
throw SaneException("Unknown device"); break;
} }
// prevent further writings by bulk write register // prevent further writings by bulk write register
@ -946,15 +1078,17 @@ void CommandSetGl847::asic_boot(Genesys_Device* dev, bool cold) const
// Write initial registers // Write initial registers
dev->interface->write_registers(dev->reg); dev->interface->write_registers(dev->reg);
/* Enable DRAM by setting a rising edge on bit 3 of reg 0x0b */ if (dev->model->model_id != ModelId::CANON_5600F) {
// Enable DRAM by setting a rising edge on bit 3 of reg 0x0b
// The initial register write also powers on SDRAM
val = dev->reg.find_reg(0x0b).value & REG_0x0B_DRAMSEL; val = dev->reg.find_reg(0x0b).value & REG_0x0B_DRAMSEL;
val = (val | REG_0x0B_ENBDRAM); val = (val | REG_0x0B_ENBDRAM);
dev->interface->write_register(REG_0x0B, val); dev->interface->write_register(REG_0x0B, val);
dev->reg.find_reg(0x0b).value = val; dev->reg.find_reg(0x0b).value = val;
/* CIS_LINE */ // TODO: remove this write
dev->reg.init_reg(0x08, REG_0x08_CIS_LINE);
dev->interface->write_register(0x08, dev->reg.find_reg(0x08).value); dev->interface->write_register(0x08, dev->reg.find_reg(0x08).value);
}
// set up end access // set up end access
dev->interface->write_0x8c(0x10, 0x0b); dev->interface->write_0x8c(0x10, 0x0b);
@ -966,8 +1100,11 @@ void CommandSetGl847::asic_boot(Genesys_Device* dev, bool cold) const
// setup internal memory layout // setup internal memory layout
gl847_init_memory_layout (dev); gl847_init_memory_layout (dev);
if (dev->model->model_id != ModelId::CANON_5600F) {
// FIXME: move to memory layout
dev->reg.init_reg(0xf8, 0x01); dev->reg.init_reg(0xf8, 0x01);
dev->interface->write_register(0xf8, dev->reg.find_reg(0xf8).value); dev->interface->write_register(0xf8, dev->reg.find_reg(0xf8).value);
}
} }
/** /**

Wyświetl plik

@ -67,6 +67,7 @@
#include "gl646.h" #include "gl646.h"
#include <cstdio> #include <cstdio>
#include <chrono>
#include <cmath> #include <cmath>
#include <vector> #include <vector>
@ -409,7 +410,7 @@ Image read_unshuffled_image_from_scanner(Genesys_Device* dev, const ScanSession&
throw SaneException("Trying to read too much data %zu (max %zu)", total_bytes, max_bytes); throw SaneException("Trying to read too much data %zu (max %zu)", total_bytes, max_bytes);
} }
if (total_bytes != max_bytes) { if (total_bytes != max_bytes) {
DBG(DBG_info, "WARNING %s: trying to read not enough data (%zu, full fill %zu\n", __func__, DBG(DBG_info, "WARNING %s: trying to read not enough data (%zu, full fill %zu)\n", __func__,
total_bytes, max_bytes); total_bytes, max_bytes);
} }
@ -425,19 +426,120 @@ Image read_unshuffled_image_from_scanner(Genesys_Device* dev, const ScanSession&
1, 1); 1, 1);
} }
if (has_flag(dev->model->flags, ModelFlag::SWAP_16BIT_DATA) && session.params.depth == 16) { if (session.params.depth == 16) {
pipeline.push_node<ImagePipelineNodeSwap16BitEndian>(); unsigned num_swaps = 0;
if (has_flag(dev->model->flags, ModelFlag::SWAP_16BIT_DATA)) {
num_swaps++;
}
#ifdef WORDS_BIGENDIAN
num_swaps++;
#endif
if (num_swaps % 2 != 0) {
dev->pipeline.push_node<ImagePipelineNodeSwap16BitEndian>();
}
} }
if (has_flag(dev->model->flags, ModelFlag::INVERT_PIXEL_DATA)) { if (has_flag(dev->model->flags, ModelFlag::INVERT_PIXEL_DATA)) {
pipeline.push_node<ImagePipelineNodeInvert>(); pipeline.push_node<ImagePipelineNodeInvert>();
} }
#ifdef WORDS_BIGENDIAN if (dev->model->is_cis && session.params.channels == 3) {
if (session.params.depth == 16) { pipeline.push_node<ImagePipelineNodeMergeMonoLines>(dev->model->line_mode_color_order);
pipeline.push_node<ImagePipelineNodeSwap16BitEndian>();
} }
if (pipeline.get_output_format() == PixelFormat::BGR888) {
pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB888);
}
if (pipeline.get_output_format() == PixelFormat::BGR161616) {
pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB161616);
}
return pipeline.get_image();
}
Image read_shuffled_image_from_scanner(Genesys_Device* dev, const ScanSession& session)
{
DBG_HELPER(dbg);
std::size_t total_bytes = 0;
std::size_t pixels_per_line = 0;
if (dev->model->asic_type == AsicType::GL842 ||
dev->model->asic_type == AsicType::GL843 ||
dev->model->model_id == ModelId::CANON_5600F)
{
pixels_per_line = session.output_pixels;
} else {
// BUG: this selects incorrect pixel number
pixels_per_line = session.params.pixels;
}
// FIXME: the current calculation is likely incorrect on non-GL843 implementations,
// but this needs checking. Note the extra line when computing size.
if (dev->model->asic_type == AsicType::GL842 ||
dev->model->asic_type == AsicType::GL843 ||
dev->model->model_id == ModelId::CANON_5600F)
{
total_bytes = session.output_total_bytes_raw;
} else {
total_bytes = session.params.channels * 2 * pixels_per_line * (session.params.lines + 1);
}
auto format = create_pixel_format(session.params.depth,
dev->model->is_cis ? 1 : session.params.channels,
dev->model->line_mode_color_order);
// auto width = get_pixels_from_row_bytes(format, session.output_line_bytes_raw);
auto width = pixels_per_line;
auto height = session.params.lines + 1; // BUG: incorrect
if (dev->model->asic_type == AsicType::GL842 ||
dev->model->asic_type == AsicType::GL843 ||
dev->model->model_id == ModelId::CANON_5600F)
{
height = session.optical_line_count;
}
Image image(width, height, format);
auto max_bytes = image.get_row_bytes() * height;
if (total_bytes > max_bytes) {
throw SaneException("Trying to read too much data %zu (max %zu)", total_bytes, max_bytes);
}
if (total_bytes != max_bytes) {
DBG(DBG_info, "WARNING %s: trying to read not enough data (%zu, full fill %zu)\n", __func__,
total_bytes, max_bytes);
}
sanei_genesys_read_data_from_scanner(dev, image.get_row_ptr(0), total_bytes);
ImagePipelineStack pipeline;
pipeline.push_first_node<ImagePipelineNodeImageSource>(image);
if (session.segment_count > 1) {
auto output_width = session.output_segment_pixel_group_count * session.segment_count;
pipeline.push_node<ImagePipelineNodeDesegment>(output_width, dev->segment_order,
session.conseq_pixel_dist,
1, 1);
}
if (session.params.depth == 16) {
unsigned num_swaps = 0;
if (has_flag(dev->model->flags, ModelFlag::SWAP_16BIT_DATA)) {
num_swaps++;
}
#ifdef WORDS_BIGENDIAN
num_swaps++;
#endif #endif
if (num_swaps % 2 != 0) {
dev->pipeline.push_node<ImagePipelineNodeSwap16BitEndian>();
}
}
if (has_flag(dev->model->flags, ModelFlag::INVERT_PIXEL_DATA)) {
pipeline.push_node<ImagePipelineNodeInvert>();
}
if (dev->model->is_cis && session.params.channels == 3) { if (dev->model->is_cis && session.params.channels == 3) {
pipeline.push_node<ImagePipelineNodeMergeMonoLines>(dev->model->line_mode_color_order); pipeline.push_node<ImagePipelineNodeMergeMonoLines>(dev->model->line_mode_color_order);
@ -514,6 +616,9 @@ void sanei_genesys_set_lamp_power(Genesys_Device* dev, const Genesys_Sensor& sen
regs_set_exposure(dev->model->asic_type, regs, sanei_genesys_fixup_exposure({0, 0, 0})); regs_set_exposure(dev->model->asic_type, regs, sanei_genesys_fixup_exposure({0, 0, 0}));
regs.set8(0x19, 0xff); regs.set8(0x19, 0xff);
} }
if (dev->model->model_id == ModelId::CANON_5600F) {
regs_set_exposure(dev->model->asic_type, regs, sanei_genesys_fixup_exposure({0, 0, 0}));
}
} }
regs.state.is_lamp_on = set; regs.state.is_lamp_on = set;
} }
@ -685,7 +790,16 @@ void compute_session_pixel_offsets(const Genesys_Device* dev, ScanSession& s,
dev->model->asic_type == AsicType::GL846 || dev->model->asic_type == AsicType::GL846 ||
dev->model->asic_type == AsicType::GL847) dev->model->asic_type == AsicType::GL847)
{ {
s.pixel_startx = (s.output_startx * s.optical_resolution) / s.params.xres; unsigned startx_xres = s.optical_resolution;
if (dev->model->model_id == ModelId::CANON_5600F) {
if (s.output_resolution == 1200) {
startx_xres /= 2;
}
if (s.output_resolution >= 2400) {
startx_xres /= 4;
}
}
s.pixel_startx = (s.output_startx * startx_xres) / s.params.xres;
s.pixel_endx = s.pixel_startx + s.optical_pixels_raw; s.pixel_endx = s.pixel_startx + s.optical_pixels_raw;
} else if (dev->model->asic_type == AsicType::GL124) } else if (dev->model->asic_type == AsicType::GL124)
@ -719,6 +833,10 @@ unsigned session_adjust_output_pixels(unsigned output_pixels,
bool adjust_output_pixels) bool adjust_output_pixels)
{ {
bool adjust_optical_pixels = !adjust_output_pixels; bool adjust_optical_pixels = !adjust_output_pixels;
if (dev.model->model_id == ModelId::CANON_5600F) {
adjust_optical_pixels = true;
adjust_output_pixels = true;
}
if (adjust_optical_pixels) { if (adjust_optical_pixels) {
auto optical_resolution = sensor.get_optical_resolution(); auto optical_resolution = sensor.get_optical_resolution();
@ -873,6 +991,7 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se
s.output_line_bytes_raw = s.output_line_bytes; s.output_line_bytes_raw = s.output_line_bytes;
s.conseq_pixel_dist = 0; s.conseq_pixel_dist = 0;
// FIXME: Use ModelFlag::SIS_SENSOR
if ((dev->model->asic_type == AsicType::GL845 || if ((dev->model->asic_type == AsicType::GL845 ||
dev->model->asic_type == AsicType::GL846 || dev->model->asic_type == AsicType::GL846 ||
dev->model->asic_type == AsicType::GL847) && dev->model->asic_type == AsicType::GL847) &&
@ -882,19 +1001,48 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se
if (s.segment_count > 1) { if (s.segment_count > 1) {
s.conseq_pixel_dist = sensor.segment_size; s.conseq_pixel_dist = sensor.segment_size;
// in case of multi-segments sensor, we have to add the width of the sensor crossed by // in case of multi-segments sensor, we have expand the scan area to sensor boundary
// the scan area if (dev->model->model_id == ModelId::CANON_5600F) {
unsigned startx_xres = s.optical_resolution;
if (dev->model->model_id == ModelId::CANON_5600F) {
if (s.output_resolution == 1200) {
startx_xres /= 2;
}
if (s.output_resolution >= 2400) {
startx_xres /= 4;
}
}
unsigned optical_startx = s.output_startx * startx_xres / s.params.xres;
unsigned optical_endx = optical_startx + s.optical_pixels;
unsigned multi_segment_size_output = s.segment_count * s.conseq_pixel_dist;
unsigned multi_segment_size_optical =
(multi_segment_size_output * s.optical_resolution) / s.output_resolution;
optical_endx = align_multiple_ceil(optical_endx, multi_segment_size_optical);
s.optical_pixels_raw = optical_endx - optical_startx;
s.optical_pixels_raw = align_multiple_floor(s.optical_pixels_raw,
4 * s.optical_resolution / s.output_resolution);
} else {
// BUG: the following code will likely scan too much. Use the CANON_5600F approach
unsigned extra_segment_scan_area = align_multiple_ceil(s.conseq_pixel_dist, 2); unsigned extra_segment_scan_area = align_multiple_ceil(s.conseq_pixel_dist, 2);
extra_segment_scan_area *= s.segment_count - 1; extra_segment_scan_area *= s.segment_count - 1;
extra_segment_scan_area = s.pixel_count_ratio.apply_inverse(extra_segment_scan_area); extra_segment_scan_area = s.pixel_count_ratio.apply_inverse(extra_segment_scan_area);
s.optical_pixels_raw += extra_segment_scan_area; s.optical_pixels_raw += extra_segment_scan_area;
} }
}
if (dev->model->model_id == ModelId::CANON_5600F) {
auto output_pixels_raw = (s.optical_pixels_raw * s.output_resolution) / s.optical_resolution;
auto output_channel_bytes_raw = multiply_by_depth_ceil(output_pixels_raw, s.params.depth);
s.output_line_bytes_raw = output_channel_bytes_raw * s.params.channels;
} else {
s.output_line_bytes_raw = multiply_by_depth_ceil( s.output_line_bytes_raw = multiply_by_depth_ceil(
(s.optical_pixels_raw * s.output_resolution) / sensor.full_resolution / s.segment_count, (s.optical_pixels_raw * s.output_resolution) / sensor.full_resolution / s.segment_count,
s.params.depth); s.params.depth);
} }
}
if (dev->model->asic_type == AsicType::GL841) { if (dev->model->asic_type == AsicType::GL841) {
if (dev->model->is_cis) { if (dev->model->is_cis) {
@ -927,8 +1075,12 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se
dev->model->asic_type == AsicType::GL846 || dev->model->asic_type == AsicType::GL846 ||
dev->model->asic_type == AsicType::GL847) dev->model->asic_type == AsicType::GL847)
{ {
if (dev->model->model_id == ModelId::CANON_5600F) {
s.output_segment_pixel_group_count = s.output_pixels / s.segment_count;
} else {
s.output_segment_pixel_group_count = s.pixel_count_ratio.apply(s.optical_pixels); s.output_segment_pixel_group_count = s.pixel_count_ratio.apply(s.optical_pixels);
} }
}
s.output_line_bytes_requested = multiply_by_depth_ceil( s.output_line_bytes_requested = multiply_by_depth_ceil(
s.params.get_requested_pixels() * s.params.channels, s.params.depth); s.params.get_requested_pixels() * s.params.channels, s.params.depth);
@ -977,7 +1129,13 @@ ImagePipelineStack build_image_pipeline(const Genesys_Device& dev, const ScanSes
auto read_data_from_usb = [&dev](std::size_t size, std::uint8_t* data) auto read_data_from_usb = [&dev](std::size_t size, std::uint8_t* data)
{ {
DBG(DBG_info, "read_data_from_usb: reading %zu bytes\n", size);
auto begin = std::chrono::high_resolution_clock::now();
dev.interface->bulk_read_data(0x45, data, size); dev.interface->bulk_read_data(0x45, data, size);
auto end = std::chrono::high_resolution_clock::now();
float us = std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count();
float speed = size / us; // bytes/us == MB/s
DBG(DBG_info, "read_data_from_usb: reading %zu bytes finished %f MB/s\n", size, speed);
return true; return true;
}; };

Wyświetl plik

@ -310,8 +310,7 @@ struct Genesys_Sensor {
int exposure_lperiod = -1; int exposure_lperiod = -1;
// the number of pixels in a single segment. // the number of pixels in a single segment. This is counted in output resolution.
// only on gl843
unsigned segment_size = 0; unsigned segment_size = 0;
// the order of the segments, if any, for the sensor. If the sensor is not segmented or uses // the order of the segments, if any, for the sensor. If the sensor is not segmented or uses

Wyświetl plik

@ -583,6 +583,26 @@ void genesys_init_frontend_tables()
s_frontends->push_back(fe); s_frontends->push_back(fe);
fe = Genesys_Frontend();
fe.id = AdcId::CANON_5600F;
fe.layout = wolfson_layout;
fe.regs = {
{ 0x01, 0x23 },
{ 0x02, 0x24 },
{ 0x03, 0x2f },
{ 0x06, 0x00 },
{ 0x08, 0x00 },
{ 0x09, 0x00 },
{ 0x20, 0x60 },
{ 0x21, 0x60 },
{ 0x22, 0x60 },
{ 0x28, 0x77 },
{ 0x29, 0x77 },
{ 0x2a, 0x77 },
};
s_frontends->push_back(fe);
fe = Genesys_Frontend(); fe = Genesys_Frontend();
fe.id = AdcId::CANON_8400F; fe.id = AdcId::CANON_8400F;
fe.layout = wolfson_layout; fe.layout = wolfson_layout;

Wyświetl plik

@ -392,6 +392,22 @@ void genesys_init_gpo_tables()
s_gpo->push_back(gpo); s_gpo->push_back(gpo);
gpo = Genesys_Gpo();
gpo.id = GpioId::CANON_5600F;
gpo.regs = {
{ 0x6b, 0x87 },
{ 0x6c, 0xf0 },
{ 0x6d, 0x5f },
{ 0x6e, 0x7f },
{ 0x6f, 0xa0 },
{ 0xa6, 0x07 },
{ 0xa7, 0x1c },
{ 0xa8, 0x00 },
{ 0xa9, 0x04 },
};
s_gpo->push_back(gpo);
gpo = Genesys_Gpo(); gpo = Genesys_Gpo();
gpo.id = GpioId::CANON_8400F; gpo.id = GpioId::CANON_8400F;
gpo.regs = { gpo.regs = {

Wyświetl plik

@ -75,6 +75,21 @@ void genesys_init_memory_layout_tables()
On GL847 and GL124, the values of the base address for scanned data must be multiplied by On GL847 and GL124, the values of the base address for scanned data must be multiplied by
1024*2=0x0800 to give address on AHB 1024*2=0x0800 to give address on AHB
*/ */
ml = MemoryLayout();
ml.models = { ModelId::CANON_5600F };
ml.regs = {
{ 0xd0, 0x0a },
{ 0xe0, 0x01 }, { 0xe1, 0x2c }, { 0xe2, 0x06 }, { 0xe3, 0x4e },
{ 0xe4, 0x06 }, { 0xe5, 0x4f }, { 0xe6, 0x0b }, { 0xe7, 0x71 },
{ 0xe8, 0x0b }, { 0xe9, 0x72 }, { 0xea, 0x10 }, { 0xeb, 0x94 },
{ 0xec, 0x10 }, { 0xed, 0x95 }, { 0xee, 0x15 }, { 0xef, 0xb7 },
{ 0xf0, 0x15 }, { 0xf1, 0xb8 }, { 0xf2, 0x1a }, { 0xf3, 0xda },
{ 0xf4, 0x1a }, { 0xf5, 0xdb }, { 0xf6, 0x1f }, { 0xf7, 0xfd },
{ 0xf8, 0x05 }
};
s_memory_layout->push_back(ml);
ml = MemoryLayout(); ml = MemoryLayout();
ml.models = { ModelId::CANON_LIDE_100 }; ml.models = { ModelId::CANON_LIDE_100 };
ml.regs = { ml.regs = {
@ -90,8 +105,7 @@ void genesys_init_memory_layout_tables()
ml = MemoryLayout(); ml = MemoryLayout();
// BUG: we shouldn't use LIDE_200 data for 5600F ml.models = { ModelId::CANON_LIDE_200 };
ml.models = { ModelId::CANON_LIDE_200, ModelId::CANON_5600F };
ml.regs = { ml.regs = {
{ 0xd0, 0x0a }, { 0xd1, 0x1f }, { 0xd2, 0x34 }, { 0xd0, 0x0a }, { 0xd1, 0x1f }, { 0xd2, 0x34 },
{ 0xe0, 0x01 }, { 0xe1, 0x24 }, { 0xe2, 0x02 }, { 0xe3, 0x91 }, { 0xe0, 0x01 }, { 0xe1, 0x24 }, { 0xe2, 0x02 }, { 0xe3, 0x91 },

Wyświetl plik

@ -894,43 +894,57 @@ void genesys_init_usb_device_tables()
model.resolutions = { model.resolutions = {
{ {
{ ScanMethod::FLATBED }, { ScanMethod::FLATBED, ScanMethod::TRANSPARENCY },
{ 4800, 2400, 1200, 600, 400, 300, 200, 150, 100, 75 }, { 4800, 2400, 1200, 600, 300, /*150*/ },
{ 4800, 2400, 1200, 600, 400, 300, 200, 150, 100, 75 }, { 4800, 2400, 1200, 600, 300, /*150*/ },
} }
}; };
model.bpp_gray_values = { 8, 16 }; model.bpp_gray_values = { 8, 16 };
model.bpp_color_values = { 8, 16 }; model.bpp_color_values = { 8, 16 };
model.x_offset = 1.1; model.x_offset = 1.5;
model.y_offset = 8.3; model.y_offset = 10.4;
model.x_size = 216.07; model.x_size = 219.00;
model.y_size = 299.0; model.y_size = 305.0;
model.y_offset_calib_white = 3.0; model.y_offset_calib_white = 2.0;
model.y_size_calib_mm = 3.0; model.y_size_calib_mm = 2.0;
model.x_offset_calib_black = 0.0; model.x_offset_calib_black = 0.0;
model.x_size_calib_mm = 217.4241; model.x_size_calib_mm = 220.5;
model.x_offset_ta = 93.0;
model.y_offset_ta = 42.4;
model.x_size_ta = 35.0;
model.y_size_ta = 230.0;
model.y_offset_sensor_to_ta = 0;
model.y_offset_calib_white_ta = 21.4;
model.y_size_calib_ta_mm = 1.0;
model.post_scan = 0.0; model.post_scan = 0.0;
model.eject_feed = 0.0; model.eject_feed = 0.0;
model.ld_shift_r = 0; model.ld_shift_r = 0;
model.ld_shift_g = 0; model.ld_shift_g = 32;
model.ld_shift_b = 0; model.ld_shift_b = 64;
model.line_mode_color_order = ColorOrder::RGB; model.line_mode_color_order = ColorOrder::RGB;
model.is_cis = true; model.is_cis = false;
model.is_sheetfed = false; model.is_sheetfed = false;
model.sensor_id = SensorId::CIS_CANON_LIDE_200; model.sensor_id = SensorId::CCD_CANON_5600F;
model.adc_id = AdcId::CANON_LIDE_200; model.adc_id = AdcId::CANON_5600F;
model.gpio_id = GpioId::CANON_LIDE_200; model.gpio_id = GpioId::CANON_5600F;
model.motor_id = MotorId::CANON_LIDE_200; model.motor_id = MotorId::CANON_5600F;
model.flags = ModelFlag::UNTESTED | model.flags = ModelFlag::SIS_SENSOR |
ModelFlag::SIS_SENSOR | ModelFlag::INVERT_PIXEL_DATA |
ModelFlag::DISABLE_ADC_CALIBRATION |
ModelFlag::DISABLE_EXPOSURE_CALIBRATION |
ModelFlag::HOST_SIDE_CALIBRATION_COMPLETE_SCAN |
ModelFlag::DARK_CALIBRATION | ModelFlag::DARK_CALIBRATION |
ModelFlag::SHADING_REPARK |
ModelFlag::UTA_NO_SECONDARY_MOTOR |
ModelFlag::CUSTOM_GAMMA; ModelFlag::CUSTOM_GAMMA;
model.buttons = GENESYS_HAS_SCAN_SW | model.buttons = GENESYS_HAS_SCAN_SW |
GENESYS_HAS_COPY_SW | GENESYS_HAS_COPY_SW |

Wyświetl plik

@ -315,6 +315,34 @@ void genesys_init_motor_tables()
s_motors->push_back(std::move(motor)); s_motors->push_back(std::move(motor));
motor = Genesys_Motor();
motor.id = MotorId::CANON_5600F;
motor.base_ydpi = 2400;
// FIXME: real limit is 134, but for some reason the motor can't acquire that speed.
profile = MotorProfile();
profile.slope = MotorSlope::create_from_steps(2500 * 2, 134 * 2, 1000);
profile.step_type = StepType::HALF;
profile.motor_vref = 0;
profile.resolutions = { 75, 150 };
motor.profiles.push_back(std::move(profile));
profile = MotorProfile();
profile.slope = MotorSlope::create_from_steps(2500 * 2, 200 * 2, 1000);
profile.step_type = StepType::QUARTER;
profile.motor_vref = 0;
profile.resolutions = { 300, 600, 1200, 2400, 4800 };
motor.profiles.push_back(std::move(profile));
profile = MotorProfile();
profile.slope = MotorSlope::create_from_steps(2500 * 2, 200 * 2, 1000);
profile.step_type = StepType::QUARTER;
profile.motor_vref = 0;
motor.fast_profiles.push_back(std::move(profile));
s_motors->push_back(std::move(motor));
motor = Genesys_Motor(); motor = Genesys_Motor();
motor.id = MotorId::CANON_8400F; motor.id = MotorId::CANON_8400F;
motor.base_ydpi = 1600; motor.base_ydpi = 1600;

Wyświetl plik

@ -1877,6 +1877,129 @@ void genesys_init_sensor_tables()
} }
sensor = Genesys_Sensor();
sensor.sensor_id = SensorId::CCD_CANON_5600F; // gl847
sensor.full_resolution = 4800;
sensor.register_dpihw = 4800;
sensor.black_pixels = 50*8;
sensor.dummy_pixel = 10;
sensor.fau_gain_white_ref = 160;
sensor.gain_white_ref = 160;
sensor.exposure = { 0x9c40, 0x9c40, 0x9c40 };
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.use_host_side_calib = true;
{
struct CustomSensorSettings {
ValueFilterAny<unsigned> resolutions;
unsigned optical_resolution;
unsigned register_dpihw;
unsigned register_dpiset;
int exposure_lperiod;
SensorExposure exposure;
Ratio pixel_count_ratio;
int output_pixel_offset;
unsigned segment_size;
std::vector<unsigned> segment_order;
StaggerConfig stagger_x;
StaggerConfig stagger_y;
GenesysRegisterSettingSet custom_regs;
};
CustomSensorSettings custom_settings[] = {
{ { 150 }, 2400, 600, 300, 4288, { 3983/2, 3983/2, 3983/2 }, Ratio{1, 8}, 10,
5418, std::vector<unsigned>{}, StaggerConfig{}, StaggerConfig{}, {
{ 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
{ 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
{ 0x52, 0x0e }, { 0x53, 0x00 }, { 0x54, 0x02 }, { 0x55, 0x04 },
{ 0x56, 0x06 }, { 0x57, 0x08 }, { 0x58, 0x52 }, { 0x59, 0x3a }, { 0x5a, 0x40 },
{ 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
}
},
{ { 300 }, 2400, 600, 600, 5472, { 4558/2, 4558/2, 4558/2 }, Ratio{1, 8}, 110,
5418, std::vector<unsigned>{}, StaggerConfig{}, StaggerConfig{}, {
{ 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
{ 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
{ 0x52, 0x0e }, { 0x53, 0x00 }, { 0x54, 0x02 }, { 0x55, 0x04 },
{ 0x56, 0x06 }, { 0x57, 0x08 }, { 0x58, 0x52 }, { 0x59, 0x3a }, { 0x5a, 0x40 },
{ 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
}
},
{ { 600 }, 2400, 600, 600, 10944, { 8701/2, 8701/2, 8701/2 }, Ratio{1, 4}, 155,
5418, std::vector<unsigned>{}, StaggerConfig{}, StaggerConfig{}, {
{ 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
{ 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
{ 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x06 }, { 0x55, 0x08 },
{ 0x56, 0x0a }, { 0x57, 0x0c }, { 0x58, 0x72 }, { 0x59, 0x5a }, { 0x5a, 0x40 },
{ 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
}
},
{ { 1200 }, 2400, 1200, 1200, 29120, { 17120/2, 17120/2, 17120/2 }, Ratio{1, 2}, 295,
5418, { 1, 0 }, StaggerConfig{}, StaggerConfig{}, {
{ 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
{ 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
{ 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x06 }, { 0x55, 0x08 },
{ 0x56, 0x0a }, { 0x57, 0x0c }, { 0x58, 0x72 }, { 0x59, 0x5a }, { 0x5a, 0x40 },
{ 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
}
},
{ { 2400 }, 2400, 2400, 2400, 43776, { 36725/2, 36725/2, 36725/2 }, Ratio{1, 1}, 600,
5418, { 0, 1, 2, 3 },
StaggerConfig{10, 15, 4, 9, 14, 19, 8, 13}, StaggerConfig{}, {
{ 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
{ 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
{ 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x06 }, { 0x55, 0x08 },
{ 0x56, 0x0a }, { 0x57, 0x0c }, { 0x58, 0x72 }, { 0x59, 0x5a }, { 0x5a, 0x40 },
{ 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
}
},
{ { 4800 }, 4800, 4800, 4800, 43776, { 36725/2, 36725/2, 36725/2 }, Ratio{1, 1}, 1000,
10784, { 0, 1, 2, 3 },
StaggerConfig{5, 9, 6, 10, 3, 7, 16, 20, 13, 17, 14, 18, 11, 15, 24, 28},
StaggerConfig{6, 0}, {
{ 0x16, 0x00 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0x2a },
{ 0x1a, 0x00 }, { 0x1b, 0x10 }, { 0x1c, 0x08 }, { 0x1d, 0x02 },
{ 0x52, 0x0a }, { 0x53, 0x0c }, { 0x54, 0x0e }, { 0x55, 0x00 },
{ 0x56, 0x02 }, { 0x57, 0x04 }, { 0x58, 0x32 }, { 0x59, 0x1a }, { 0x5a, 0x40 },
{ 0x74, 0x00 }, { 0x75, 0x33 }, { 0x76, 0x33 },
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, { 0x87, 0x00 },
}
}
};
for (const auto& setting : custom_settings) {
for (auto method : { ScanMethod::FLATBED, ScanMethod::TRANSPARENCY }) {
sensor.method = method;
sensor.resolutions = setting.resolutions;
sensor.optical_resolution = setting.optical_resolution;
sensor.register_dpihw = setting.register_dpihw;
sensor.register_dpiset = setting.register_dpiset;
sensor.shading_resolution = setting.resolutions.values().front();
sensor.exposure_lperiod = setting.exposure_lperiod;
sensor.exposure = setting.exposure;
sensor.pixel_count_ratio = setting.pixel_count_ratio;
sensor.output_pixel_offset = setting.output_pixel_offset;
sensor.segment_size = setting.segment_size;
sensor.segment_order = setting.segment_order;
sensor.stagger_x = setting.stagger_x;
sensor.stagger_y = setting.stagger_y;
sensor.custom_regs = setting.custom_regs;
s_sensors->push_back(sensor);
}
}
}
sensor = Genesys_Sensor(); sensor = Genesys_Sensor();
sensor.sensor_id = SensorId::CCD_CANON_8400F; // gl843 sensor.sensor_id = SensorId::CCD_CANON_8400F; // gl843
sensor.full_resolution = 3200; sensor.full_resolution = 3200;