#include "hardware.h" #include "./cis/FpgaComm.h" #include "./cis/gvideoisp1.h" #include "./motor/motorboard.h" #include #include ///////////////////////////////////////////////////////////////////////////////////////////////////////// // scanner_hw static std::string device_opt_json[] = { "{\"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\"},\"scan-mode\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u626b\\u63cf\\u5f20\\u6570\",\"desc\":\"\\u9009\\u62e9\\u6307\\u5b9a\\u6570\\u91cf\\u626b\\u63cf\\u6216\\u8fde\\u7eed\\u626b\\u63cf\",\"type\":\"string\",\"fix-id\":34862,\"ui-pos\":15,\"auth\":0,\"size\":24,\"cur\":\"\\u8fde\\u7eed\\u626b\\u63cf\",\"default\":\"\\u8fde\\u7eed\\u626b\\u63cf\",\"range\":[\"\\u8fde\\u7eed\\u626b\\u63cf\",\"\\u626b\\u63cf\\u6307\\u5b9a\\u5f20\\u6570\"],\"depend\":\"is-wait-scan==false\"},\"scan-count\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\" \\u626b\\u63cf\\u6570\\u91cf\",\"desc\":\"\\u626b\\u63cf\\u6307\\u5b9a\\u6570\\u91cf\",\"type\":\"int\",\"fix-id\":34863,\"ui-pos\":16,\"auth\":0,\"size\":4,\"cur\":-1,\"default\":-1,\"depend\":\"scan-mode.enabled&&scan-mode==\\u626b\\u63cf\\u6307\\u5b9a\\u5f20\\u6570\"},\"is-auto-strength\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u81ea\\u52a8\\u5206\\u7eb8\\u5f3a\\u5ea6\",\"desc\":\"\\u626b\\u63cf\\u4eea\\u81ea\\u52a8\\u4fee\\u6b63\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"bool\",\"fix-id\":34876,\"ui-pos\":27,\"auth\":0,\"size\":4,\"cur\":false,\"default\":false},\"feed-strength-value\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\" \\u8fdb\\u7eb8\\u5931\\u8d25\\u7387\",\"desc\":\"\\u9ad8\\u4e8e\\u8be5\\u503c\\u65f6\\u626b\\u63cf\\u4eea\\u5c06\\u8c03\\u6574\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"float\",\"fix-id\":34877,\"ui-pos\":28,\"auth\":0,\"size\":8,\"cur\":0.000000,\"default\":0.000000,\"range\":{\"min\":0.100000,\"max\":0.900000,\"step\":0.080000},\"depend\":\"is-auto-strength==true\"},\"feed-strength\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5206\\u7eb8\\u5f3a\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u4eea\\u7684\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"string\",\"fix-id\":34874,\"ui-pos\":30,\"auth\":0,\"size\":12,\"cur\":\"\\u4e00\\u822c\",\"default\":\"\\u4e00\\u822c\",\"range\":[\"\\u5f31\",\"\\u4e00\\u822c\",\"\\u5f3a\"],\"depend\":\"is-auto-strength!=true\"},\"time-to-sleep\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u4f11\\u7720\\u65f6\\u95f4\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u4eea\\u7684\\u4f11\\u7720\\u65f6\\u95f4\",\"type\":\"string\",\"fix-id\":34875,\"ui-pos\":33,\"auth\":0,\"size\":16,\"cur\":\"\\u4e0d\\u4f11\\u7720\",\"default\":\"\\u4e0d\\u4f11\\u7720\",\"range\":[\"\\u4e0d\\u4f11\\u7720\",\"\\u4e94\\u5206\\u949f\",\"\\u5341\\u5206\\u949f\",\"\\u534a\\u5c0f\\u65f6\",\"\\u4e00\\u5c0f\\u65f6\",\"\\u4e24\\u5c0f\\u65f6\",\"\\u56db\\u5c0f\\u65f6\"]},\"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\\u9053\\uff09\",\"desc\":\"\\u80cc\\u9762\\u7eff\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":34,\"auth\":0,\"size\":4,\"cur\":0,\"default\":0,\"range\":{\"min\":-1000,\"max\":1000,\"step\":1}},\"expo-br\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u66dd\\u5149\\u5ea6\\uff08\\u80cc\\u9762\\u7ea2\\u8272\\u901a\\u9053\\uff09\",\"desc\":\"\\u80cc\\u9762\\u7ea2\\u8272\\u901a\\u9053\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"ui-pos\":33,\"auth\":0,\"size\":4,\"cur\":0,\"default\":0,\"range\":{\"min\":-1000,\"max\":1000,\"step\":1}},\"gain-f\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u6b63\\u9762\\uff09\",\"desc\":\"\\u6b63\\u9762\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":40,\"auth\":0,\"size\":4,\"cur\":0,\"default\":0,\"range\":{\"min\":-1000,\"max\":1000,\"step\":1}},\"gain-b\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\uff08\\u80cc\\u9762\\uff09\",\"desc\":\"\\u80cc\\u9762\\u7684\\u589e\\u76ca\\u91cf\",\"type\":\"int\",\"ui-pos\":41,\"auth\":0,\"size\":4,\"cur\":0,\"default\":0,\"range\":{\"min\":-1000,\"max\":1000,\"step\":1}},\"off-f\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u6b63\\u9762\\uff09\",\"desc\":\"\\u6b63\\u9762\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":45,\"auth\":0,\"size\":4,\"cur\":0,\"default\":0,\"range\":{\"min\":-100,\"max\":100,\"step\":1}},\"off-b\":{\"cat\":\"none\",\"group\":\"CIS\",\"title\":\"\\u589e\\u76ca\\u8865\\u507f\\uff08\\u80cc\\u9762\\uff09\",\"desc\":\"\\u80cc\\u9762\\u7684\\u589e\\u76ca\\u8865\\u507f\\u91cf\",\"type\":\"int\",\"ui-pos\":46,\"auth\":0,\"size\":4,\"cur\":0,\"default\":0,\"range\":{\"min\":-100,\"max\":100,\"step\":1}},\"paper-on\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u7eb8\\u5f20\\u5c31\\u7eea\",\"desc\":\"\\u7eb8\\u5f20\\u5df2\\u7ecf\\u5728\\u8fdb\\u7eb8\\u53f0\\u4e0a\\u653e\\u7f6e\\u597d\",\"type\":\"bool\",\"fix-id\":34912,\"ui-pos\":10,\"auth\":0,\"readonly\":true,\"size\":4,\"auto\":false,\"ownread\":true,\"cur\":false,\"default\":false},\"double-chk\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u53cc\\u5f20\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u6709\\u4e24\\u5f20\\u6216\\u8005\\u591a\\u5f20\\u7eb8\\u540c\\u65f6\\u6413\\u8fdb\",\"type\":\"string\",\"ui-pos\":18,\"auth\":0,\"size\":16,\"cur\":\"\\u8d85\\u58f0\\u6ce2\",\"default\":\"\\u8d85\\u58f0\\u6ce2\",\"range\":[\"\\u8d85\\u58f0\\u6ce2\",\"\\u7981\\u7528\"]},\"is-staple\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u88c5\\u8ba2\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u6709\\u8ba2\\u4e66\\u9489\\u5b58\\u5728\",\"type\":\"bool\",\"fix-id\":34861,\"ui-pos\":20,\"auth\":0,\"size\":4,\"cur\":true,\"default\":true},\"motor-speed\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u8d70\\u7eb8\\u901f\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u8d70\\u7eb8\\u7535\\u673a\\u7684\\u901f\\u5ea6\\uff0c\\u5f20\\/\\u5206\\uff08PPM\\uff09\",\"type\":\"int\",\"ui-pos\":25,\"auth\":0,\"size\":4,\"cur\":100,\"default\":100,\"range\":[{\"dev-model!=G200\":70},{\"dev-model!=G200\":80},{\"dev-model!=G200\":90},100,{\"dev-model==G200\":110},{\"dev-model==G200\":120},{\"dev-model==G200\":130}]},\"is-check-askew\":{\"cat\":\"none\",\"group\":\"feeder\",\"title\":\"\\u6b6a\\u659c\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u8fdb\\u7eb8\\u662f\\u5426\\u6b6a\\u659c\",\"type\":\"bool\",\"fix-id\":34868,\"ui-pos\":22,\"auth\":0,\"size\":4,\"cur\":true,\"default\":true},\"askew-range\":{\"cat\":\"none\",\"group\":\"feeder", "\",\"title\":\"\\u6b6a\\u659c\\u5bb9\\u5fcd\\u5ea6\",\"desc\":\"\\u503c\\u8d8a\\u5c0f\\uff0c\\u80fd\\u5bb9\\u5fcd\\u5f97\\u9001\\u5165\\u6587\\u7a3f\\u6b6a\\u659c\\u89d2\\u5ea6\\u8d8a\\u5c0f\",\"type\":\"int\",\"fix-id\":34869,\"ui-pos\":23,\"auth\":0,\"size\":4,\"cur\":3,\"default\":3,\"range\":{\"min\":1,\"max\":7,\"step\":1},\"depend\":\"is-check-askew==true\"}}" }; ///////////////////////////////////////////////////////////////////////////////////////////////////////// // 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]); #define OPT_HANDLER(name) \ auto name = [this](void* value) -> void 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; }; 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; 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; }; 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; if(family_ == "G200") { speed -= 100; // 100 110 120 130 } else { speed -= 70; // 70 80 90 100 } 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(cntm) { }; OPT_HANDLER(cnt) { scan_count_ = *(int*)value; }; OPT_HANDLER(afs) { }; OPT_HANDLER(ff) { }; OPT_HANDLER(fs) { }; OPT_HANDLER(slp) { }; opt_handler_[SANE_FULL_NAME(IS_CHECK_STAPLE)] = staple; opt_handler_[SANE_FULL_NAME(IS_CHECK_ASKEW)] = screw; opt_handler_[SANE_FULL_NAME(ASKEW_RANGE)] = screwl; opt_handler_[SANE_FULL_NAME(DOUBLE_CHECK)] = dbchk; opt_handler_[SANE_FULL_NAME(MOTOR_SPEED)] = motsp; opt_handler_[SANE_FULL_NAME(DEVICE_MODEL)] = fm; opt_handler_[SANE_FULL_NAME(SCAN_MODE)] = cntm; opt_handler_[SANE_FULL_NAME(SCAN_COUNT)] = cnt; opt_handler_[SANE_FULL_NAME(IS_AUTO_FEED_STRENGTH)] = afs; opt_handler_[SANE_FULL_NAME(FEED_STRENGTH_VALUE)] = ff; opt_handler_[SANE_FULL_NAME(FEED_STRENGTH)] = fs; opt_handler_[SANE_FULL_NAME(TIME_TO_SLEEP)] = slp; } void scanner_hw::thread_image_capture(void) { PACKIMAGE img; memset(&img, 0, sizeof(img)); do { size_t size = 0; int ind = -1; void* frame = camera_->read_frame(1000, size, ind); while(frame) { dyn_mem_ptr mem = dyn_mem::memory(size); camera_->add_v4l2_memory(ind); img.pos.paper_ind++; img.pos.status = IMG_STATUS_OK; img_handler_(mem, true, &img); if(img.pos.paper_ind == scan_count_ || is_scan_fatal()) break; motor_->pick_paper(); frame = camera_->read_frame(1000, size, ind); } }while(auto_scan_); } bool scanner_hw::is_scan_fatal(void) { return false; } // 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) { 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) { if(scanning_) // 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) { 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()); 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_); motor_->set_screw_level(screw_chk_level_); motor_->set_speed_mode(motor_speed_); motor_->set_auto_paper(auto_scan_); 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) { if(!camera_.get() || !motor_.get() || !img_controller_.get()) return SCANNER_ERR_DEVICE_NOT_READY; motor_->clear_error(); if(!motor_->paper_ready() && !auto_scan_) return SCANNER_ERR_DEVICE_NO_PAPER; camera_->start(); return SCANNER_ERR_OK; } int scanner_hw::stop_scan(void) { auto_scan_ = false; if(motor_.get()) { motor_->set_auto_paper(false); motor_->stop(); } if(camera_.get()) camera_->stop(); return 0; } int scanner_hw::close(void) { img_controller_.reset(); if(motor_.get()) { motor_->stop(); motor_.reset(); } if(camera_.get()) { camera_->stop(); camera_->close(); camera_.reset(); } return 0; }