newtx/hardware/hardware.cpp

362 lines
18 KiB
C++
Raw Normal View History

#include "hardware.h"
#include "./cis/FpgaComm.h"
#include "./cis/gvideoisp1.h"
#include "./motor/motorboard.h"
#include <huagao/hgscanner_error.h>
#include <sane/sane_ex.h>
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// scanner_hw
static std::string device_opt_json[] = {
2023-12-29 02:53:04 +00:00
"{\"mode\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u989c\\u8272\\u6a21\\u5f0f\",\"desc\":\"\\u9009\\u62e9\\u955c\\u5934\\u8272\\u5f69\\u5de5\\u4f5c\\u6a21\\u5f0f\",\"type\":\"string\",\"fix-id\":34819,\"ui-pos\":10,\"auth\":0,\"size\":12,\"cur\":\"\\u5f69\\u8272\",\"default\":\"\\u5f69\\u8272\",\"range\":[\"\\u5f69\\u8272\",\"\\u7070\\u5ea6\"]},\"resolution\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6e\\u955c\\u5934\\u5de5\\u4f5c\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"fix-id\":34840,\"ui-pos\":11,\"auth\":0,\"size\":4,\"cur\":300,\"default\":300,\"range\":[200,300]},\"is-wait-scan\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5f85\\u7eb8\\u626b\\u63cf\",\"desc\":\"\\u542f\\u7528\\u540e\\uff0c\\u6587\\u7a3f\\u653e\\u5165\\u626b\\u63cf\\u4eea\\u65f6\\u5c06\\u81ea\\u52a8\\u542f\\u52a8\\u626b\\u63cf\",\"type\":\"bool\",\"fix-id\":34873,\"ui-pos\":12,\"auth\":0,\"size\":4,\"cur\":false,\"default\":false},\"wait-scan-exit\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5f85\\u7eb8\\u626b\\u63cf\\u9000\\u51fa\\u65f6\\u95f4\",\"desc\":\"\\u8bbe\\u7f6e\\u7ed3\\u675f\\u5f85\\u7eb8\\u626b\\u63cf\\u7684\\u65f6\\u95f4\",\"type\":\"string\",\"fix-id\":34920,\"ui-pos\":13,\"auth\":0,\"size\":16,\"cur\":\"60s\",\"default\":\"60s\",\"range\":[\"15s\",\"30s\",\"60s\",\"2min\",\"4min\",\"8min\"],\"depend\":\"is-wait-scan==true\"},\"baud\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u6ce2\\u7279\\u7387\",\"desc\":\"CIS\\u63a7\\u5236\\u901a\\u4fe1\\u901f\\u7387\",\"type\":\"int\",\"ui-pos\":20,\"auth\":0,\"size\":4,\"cur\":921600,\"default\":921600,\"range\":[110,300,600,1200,2400,4800,9600,19200,38400,57600,115200,500000,921600,1500000]},\"act-after\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u5ef6\\u8fdf\\u54cd\\u5e94\",\"desc\":\"\\u91c7\\u96c6\\u5934\\u63a5\\u53d7\\u547d\\u4ee4\\u540e\\u7684\\u52a8\\u4f5c\\u5ef6\\u8fdf\\u65f6\\u95f4\",\"type\":\"int\",\"ui-pos\":21,\"auth\":0,\"unit\":\"microsec\",\"size\":4,\"cur\":1000,\"default\":1000},\"frame-h\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u5e27\\u9ad8\\u5ea6\",\"desc\":\"\\u91c7\\u96c6\\u5934\\u6bcf\\u4e00\\u5e27\\u7684\\u91c7\\u96c6\\u9ad8\\u5ea6\",\"type\":\"int\",\"ui-pos\":22,\"auth\":0,\"size\":4,\"cur\":12,\"default\":12},\"sample\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u91c7\\u6837\\u9891\\u7387\",\"desc\":\"\\u91c7\\u6837\\u9891\\u7387\",\"type\":\"int\",\"ui-pos\":23,\"auth\":0,\"size\":4,\"cur\":256,\"default\":256},\"expo-fb\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u6b63\\u9762\\u84dd\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u6b63\\u9762\\u84dd\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":32,\"auth\":0,\"size\":4,\"cur\":0,\"default\":0,\"range\":{\"min\":-1000,\"max\":1000,\"step\":1}},\"expo-fg\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u6b63\\u9762\\u7eff\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u6b63\\u9762\\u7eff\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":31,\"auth\":0,\"size\":4,\"cur\":0,\"default\":0,\"range\":{\"min\":-1000,\"max\":1000,\"step\":1}},\"expo-fr\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u6b63\\u9762\\u7ea2\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u6b63\\u9762\\u7ea2\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":30,\"auth\":0,\"size\":4,\"cur\":0,\"default\":0,\"range\":{\"min\":-1000,\"max\":1000,\"step\":1}},\"expo-bb\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u80cc\\u9762\\u84dd\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u80cc\\u9762\\u84dd\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":35,\"auth\":0,\"size\":4,\"cur\":0,\"default\":0,\"range\":{\"min\":-1000,\"max\":1000,\"step\":1}},\"expo-bg\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u80cc\\u9762\\u7eff\\u8272\\u901a\\u9
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// scanner_hw
scanner_hw::scanner_hw()
{
set_where("hardware");
init();
}
scanner_hw::~scanner_hw()
{
close();
}
void scanner_hw::init(void)
{
std::string text("");
for(auto& v: device_opt_json)
text += v;
set_opt_json_text(&text[0]);
2023-12-19 09:11:41 +00:00
auto a = [this](void* value) -> void
{
auto_scan_ = *(bool*)value;
};
auto e = [this](void* value) -> void
{
if(strcmp((char*)value, "15s") == 0)
time_to_exit_auto_scan_ = 15;
else if(strcmp((char*)value, "30s") == 0)
time_to_exit_auto_scan_ = 30;
else if(strcmp((char*)value, "2min") == 0)
time_to_exit_auto_scan_ = 120;
else if(strcmp((char*)value, "4min") == 0)
time_to_exit_auto_scan_ = 240;
else if(strcmp((char*)value, "8min") == 0)
time_to_exit_auto_scan_ = 480;
else
time_to_exit_auto_scan_ = 60;
};
auto m = [this](void* value) -> void
{
if(strcmp((char*)value, "\347\201\260\345\272\246") == 0)
mode_ = (char*)value;
else
mode_ = "\345\275\251\350\211\262";
};
auto r = [this](void* value) -> void
{
if(*(int*)value <= 200)
dpi_ = 200;
else
dpi_ = 300;
};
auto b = [this](void* value) -> void
{
baud_ = *(int*)value;
};
auto d = [this](void* value) -> void
{
delay_ = *(int*)value;
};
auto f = [this](void* value) -> void
{
frame_h_ = *(int*)value;
};
auto s = [this](void* value) -> void
{
sample_ = *(int*)value;
};
auto efb = [this](void* value) -> void
{
exposure_[SIDE_FRONT][COLOR_IND_BLUE] = *(int*)value;
};
auto efg = [this](void* value) -> void
{
exposure_[SIDE_FRONT][COLOR_IND_GREEN] = *(int*)value;
};
auto efr = [this](void* value) -> void
{
exposure_[SIDE_FRONT][COLOR_IND_RED] = *(int*)value;
};
auto ebb = [this](void* value) -> void
{
exposure_[SIDE_BACK][COLOR_IND_BLUE] = *(int*)value;
};
auto ebg = [this](void* value) -> void
{
exposure_[SIDE_BACK][COLOR_IND_GREEN] = *(int*)value;
};
auto ebr = [this](void* value) -> void
{
exposure_[SIDE_BACK][COLOR_IND_RED] = *(int*)value;
};
auto gf = [this](void* value) -> void
{
gain_[SIDE_FRONT] = *(int*)value;
};
auto gb = [this](void* value) -> void
{
gain_[SIDE_BACK] = *(int*)value;
};
auto of = [this](void* value) -> void
{
off_[SIDE_FRONT] = *(int*)value;
};
auto ob = [this](void* value) -> void
{
off_[SIDE_BACK] = *(int*)value;
};
2023-12-19 09:11:41 +00:00
CLEAN_ARRAY(exposure_);
CLEAN_ARRAY(gain_);
CLEAN_ARRAY(off_);
opt_handler_[SANE_FULL_NAME(WAIT_TO_SCAN)] = a;
opt_handler_[SANE_FULL_NAME(WAIT_SCAN_EXIT)] = e;
opt_handler_[SANE_FULL_NAME(COLOR_MODE)] = m;
opt_handler_[SANE_FULL_NAME(RESOLUTION)] = r;
opt_handler_[SANE_FULL_NAME(CIS_BAUD)] = b;
opt_handler_[SANE_FULL_NAME(CIS_DELAY)] = d;
opt_handler_[SANE_FULL_NAME(CIS_FRAME_H)] = f;
opt_handler_[SANE_FULL_NAME(CIS_SAMPLE)] = s;
opt_handler_[SANE_FULL_NAME(CIS_EXPO_FB)] = efb;
opt_handler_[SANE_FULL_NAME(CIS_EXPO_FG)] = efg;
opt_handler_[SANE_FULL_NAME(CIS_EXPO_FR)] = efr;
opt_handler_[SANE_FULL_NAME(CIS_EXPO_BB)] = ebb;
opt_handler_[SANE_FULL_NAME(CIS_EXPO_BG)] = ebg;
opt_handler_[SANE_FULL_NAME(CIS_EXPO_BR)] = ebr;
opt_handler_[SANE_FULL_NAME(CIS_GAIN_FRONT)] = gf;
opt_handler_[SANE_FULL_NAME(CIS_GAIN_BACK)] = gb;
2023-12-19 09:11:41 +00:00
opt_handler_[SANE_FULL_NAME(CIS_OFFSET_FRONT)] = of;
opt_handler_[SANE_FULL_NAME(CIS_OFFSET_BACK)] = ob;
auto staple = [this](void* value) -> void
{
staple_chk_ = *(bool*)value;
};
auto screw = [this](void* value) -> void
{
screw_chk_ = *(bool*)value;
};
2023-12-29 02:53:04 +00:00
auto screwl = [this](void* value) -> void
{
screw_chk_level_ = *(int*)value;
};
auto dbchk = [this](void* value) -> void
{
double_chk_ = strcmp((char*)value, "\347\246\201\347\224\250") != 0;
};
auto motsp = [this](void* value) -> void
{
int speed = *(int*)value;
2023-12-29 02:53:04 +00:00
if(family_ == "G100")
{
speed -= 70; // 70 80 90 100
}
else
2023-12-29 02:53:04 +00:00
{
speed -= 100; // 100 110 120 130
}
switch(speed)
{
case 10:
motor_speed_ = SPEED_PPM_BASE_10;
break;
case 20:
motor_speed_ = SPEED_PPM_BASE_20;
break;
case 30:
motor_speed_ = SPEED_PPM_BASE_30;
break;
default:
motor_speed_ = SPEED_PPM_BASE;
break;
}
};
auto fm = [this](void* value) -> void
{
family_ = (char*)value;
utils::to_log(LOG_LEVEL_DEBUG, "Device family set as: %s\n", family_.c_str());
};
opt_handler_[SANE_FULL_NAME(IS_CHECK_STAPLE)] = staple;
opt_handler_[SANE_FULL_NAME(IS_CHECK_ASKEW)] = screw;
2023-12-29 02:53:04 +00:00
opt_handler_[SANE_FULL_NAME(ASKEW_RANGE)] = screwl;
opt_handler_[SANE_FULL_NAME(DOUBLE_CHECK)] = dbchk;
opt_handler_[SANE_FULL_NAME(MOTOR_SPEED)] = motsp;
2023-12-29 02:53:04 +00:00
opt_handler_[SANE_FULL_NAME(DEVICE_MODEL)] = fm;
}
// sane_opt_provider
char* scanner_hw::get_value(const char* name, void* value, size_t* size, int* err)
{
char *ret = nullptr;
if(err)
*err = SCANNER_ERR_OK;
if(strcmp(name, SANE_FULL_NAME(PAPER_ON)) == 0)
{
2023-12-25 02:08:37 +00:00
ret = (char*)malloc(sizeof(int));
*(int*)ret = 0;
*(bool*)ret = paper_on_;
if(size)
*size = sizeof(bool);
}
else if(err)
*err = SCANNER_ERR_DEVICE_NOT_FOUND;
return ret;
}
int scanner_hw::set_value(const char* name, void* val)
{
2023-12-29 02:53:04 +00:00
if(img_controller_.get()) // working, no set
{
return SCANNER_ERR_DEVICE_BUSY;
}
if(opt_handler_.count(name))
{
opt_handler_[name](val);
return 0;
}
else
{
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
}
}
// operation ...
int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler)
{
2023-12-29 02:53:04 +00:00
this->close();
if(!image_handler)
return SCANNER_ERR_INVALID_PARAMETER;
img_handler_ = image_handler;
img_controller_.reset(new FpgaComm(baud_));
img_controller_->setColorMode(mode_ == "\345\275\251\350\211\262" ? COLOR_MODE : GRAY_MODE);
img_controller_->setDpi(dpi_ == 200 ? DPI_200 : DPI_300);
img_controller_->setFrameHeight(frame_h_);
img_controller_->setDelayTime(delay_);
img_controller_->setSample(sample_);
void(FpgaComm::* exposure[])(int) = {&FpgaComm::setAExposureB, &FpgaComm::setAExposureG
, &FpgaComm::setAExposureR, &FpgaComm::setBExposureB, &FpgaComm::setBExposureG, &FpgaComm::setBExposureR};
for(int i = 0; i < SIDE_COUNT; ++i)
{
for(int j = 0; j < COLOR_IND_COUNT; ++j)
(img_controller_.get()->*exposure[i * SIDE_COUNT + j])(exposure_[i][j]);
}
for(int i = 0; i < FpgaComm::CIS_SECTOR_COUNT; ++i)
img_controller_->setAGain(i, gain_[SIDE_FRONT]);
for(int i = 0; i < FpgaComm::CIS_SECTOR_COUNT; ++i)
img_controller_->setBGain(i, gain_[SIDE_BACK]);
for(int i = 0; i < FpgaComm::CIS_SECTOR_COUNT; ++i)
img_controller_->setAOffset(i, off_[SIDE_FRONT]);
for(int i = 0; i < FpgaComm::CIS_SECTOR_COUNT; ++i)
img_controller_->setBOffset(i, off_[SIDE_BACK]);
camera_.reset(new GVideoISP1());
2023-12-29 02:53:04 +00:00
camera_->open(0, 0);
motor_.reset(new MotorBoard());
motor_->set_double_inpect(double_chk_);
motor_->set_staple_inpect(staple_chk_);
motor_->set_screw_inpect(screw_chk_);
2023-12-29 02:53:04 +00:00
motor_->set_screw_level(screw_chk_level_);
motor_->set_speed_mode(motor_speed_);
2023-12-29 02:53:04 +00:00
unsigned int val = 0;
if(motor_->read(PORT_CONFIG, val))
utils::to_log(LOG_LEVEL_DEBUG, "MotorBoard config : %p\n", val);
else
utils::to_log(LOG_LEVEL_FATAL, "Get motor-board config failed.\n");
if(motor_->read(PORT_STATUS, val))
utils::to_log(LOG_LEVEL_DEBUG, "MotorBoard status : %p\n", val);
else
utils::to_log(LOG_LEVEL_FATAL, "Get motor-board status failed.\n");
if(motor_->read(PORT_MODE, val))
utils::to_log(LOG_LEVEL_DEBUG, "MotorBoard mode : %p\n", val);
else
utils::to_log(LOG_LEVEL_FATAL, "Get motor-board mode failed.\n");
if(motor_->read(PORT_VERSION, val))
utils::to_log(LOG_LEVEL_DEBUG, "MotorBoard version: %p\n", val);
else
utils::to_log(LOG_LEVEL_FATAL, "Get motor-board version failed.\n");
if(motor_->read(PORT_CONFIG_EX, val))
utils::to_log(LOG_LEVEL_DEBUG, "MotorBoard confige: %p\n", val);
else
utils::to_log(LOG_LEVEL_FATAL, "Get motor-board confige failed.\n");
return SCANNER_ERR_OK;
}
int scanner_hw::start_scan(void)
{
2023-12-29 02:53:04 +00:00
if(!camera_.get() || !motor_.get() || !img_controller_.get())
return EBADF;
2023-12-29 02:53:04 +00:00
motor_->clear_error();
camera_->start();
return 0;
}
int scanner_hw::stop_scan(void)
{
2023-12-29 02:53:04 +00:00
if(motor_.get())
motor_->stop();
if(camera_.get())
camera_->stop();
return 0;
}
int scanner_hw::close(void)
{
2023-12-29 02:53:04 +00:00
img_controller_.reset();
if(motor_.get())
{
2023-12-29 02:53:04 +00:00
motor_->stop();
motor_.reset();
}
if(camera_.get())
{
camera_->stop();
camera_->close();
camera_.reset();
}
return 0;
}