// hardware drivers // // Contains: CIS, MotorBoard, ... // // Date: 2023-12-18 #include #include #include #include #include #include // image handler callback proto // // dyn_mem_ptr: image data buffer, or be uint32_t if bool was false // // bool: true - image, dyn_mem_ptr is image data buffer; false - dyn_mem_ptr is an uint32_t code of hardware event // // LPPACKIMAGE: image information, ignored when bool is false #define IMAGE_HANDLER_PROTO void(dyn_mem_ptr, bool, LPPACKIMAGE) class FpgaComm; class GVideoISP1; class MotorBoard; class scanner_hw : public sane_opt_provider { std::function img_handler_ = std::function(); bool scanning_ = false; int time_to_exit_auto_scan_ = 60; // seconds std::unique_ptr img_controller_; std::unique_ptr camera_; std::unique_ptr motor_; enum { SIDE_FRONT = 0, SIDE_BACK, SIDE_COUNT, }; enum { COLOR_IND_BLUE = 0, COLOR_IND_GREEN, COLOR_IND_RED, COLOR_IND_COUNT, }; std::string mode_; std::string family_ = "G200"; volatile bool auto_scan_ = false; int scan_count_ = -1; int dpi_ = 300; int baud_ = 921600; int delay_ = 1000; int frame_h_ = 12; int sample_ = 256; int exposure_[SIDE_COUNT][COLOR_IND_COUNT]; int gain_[SIDE_COUNT]; int off_[SIDE_COUNT]; bool staple_chk_ = true; bool screw_chk_ = true; int screw_chk_level_ = 3; bool paper_on_ = false; bool double_chk_ = true; int motor_speed_ = /*SPEED_PPM_100*/0; std::map> opt_handler_; void init(void); void thread_image_capture(void); bool is_scan_fatal(void); public: scanner_hw(); protected: ~scanner_hw(); // sane_opt_provider public: // return malloc(), real data size stored in parameter 'size'. invoker should free() the returned value virtual char* get_value(const char* name, void* value, size_t* size, int* err = nullptr) override; virtual int set_value(const char* name, void* val) override; // operation ... public: int open(std::function image_handler); int start_scan(void); int stop_scan(void); int close(void); }; // { // "mode": { // "cat": "none", // "group": "CIS", // "title": "颜色模式", // "desc": "选择镜头色彩工作模式", // "type": "string", // "fix-id": 34819, // "ui-pos": 10, // "auth": 0, // "size": 12, // "cur": "彩色", // "default": "彩色", // "range": ["彩色", "灰度"] // }, // "resolution": { // "cat": "none", // "group": "CIS", // "title": "分辨率", // "desc": "设置镜头工作的分辨率", // "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": "待纸扫描", // "desc": "启用后,文稿放入扫描仪时将自动启动扫描", // "type": "bool", // "fix-id": 34873, // "ui-pos": 12, // "auth": 0, // "size": 4, // "cur": false, // "default": false // }, // "wait-scan-exit": { // "cat": "base", // "group": "feeder", // "title": "待纸扫描退出时间", // "desc": "设置结束待纸扫描的时间", // "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": "扫描张数", // "desc": "选择指定数量扫描或连续扫描", // "type": "string", // "fix-id": 34862, // "ui-pos": 15, // "auth": 0, // "size": 24, // "cur": "连续扫描", // "default": "连续扫描", // "range": ["连续扫描", "扫描指定张数"], // "depend": "is-wait-scan==false" // }, // "scan-count": { // "cat": "base", // "group": "feeder", // "title": " 扫描数量", // "desc": "扫描指定数量", // "type": "int", // "fix-id": 34863, // "ui-pos": 16, // "auth": 0, // "size": 4, // "cur": -1, // "default": -1, // "depend": "scan-mode.enabled&&scan-mode==扫描指定张数" // }, // "is-auto-strength": { // "cat": "base", // "group": "feeder", // "title": "自动分纸强度", // "desc": "扫描仪自动修正分纸力度", // "type": "bool", // "fix-id": 34876, // "ui-pos": 27, // "auth": 0, // "size": 4, // "cur": false, // "default": false // }, // "feed-strength-value": { // "cat": "base", // "group": "feeder", // "title": " 进纸失败率", // "desc": "高于该值时扫描仪将调整分纸力度", // "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": "分纸强度", // "desc": "设置扫描仪的分纸力度", // "type": "string", // "fix-id": 34874, // "ui-pos": 30, // "auth": 0, // "size": 12, // "cur": "一般", // "default": "一般", // "range": ["弱", "一般", "强"], // "depend": "is-auto-strength!=true" // }, // "time-to-sleep": { // "cat": "base", // "group": "feeder", // "title": "休眠时间", // "desc": "设置扫描仪的休眠时间", // "type": "string", // "fix-id": 34875, // "ui-pos": 33, // "auth": 0, // "size": 16, // "cur": "不休眠", // "default": "不休眠", // "range": ["不休眠", "五分钟", "十分钟", "半小时", "一小时", "两小时", "四小时"] // }, // "baud": { // "cat": "none", // "group": "CIS", // "title": "波特率", // "desc": "CIS控制通信速率", // "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": "延迟响应", // "desc": "采集头接受命令后的动作延迟时间", // "type": "int", // "ui-pos": 21, // "auth": 0, // "unit": "microsec", // "size": 4, // "cur": 1000, // "default": 1000 // }, // "frame-h": { // "cat": "none", // "group": "CIS", // "title": "帧高度", // "desc": "采集头每一帧的采集高度", // "type": "int", // "ui-pos": 22, // "auth": 0, // "size": 4, // "cur": 12, // "default": 12 // }, // "sample": { // "cat": "none", // "group": "CIS", // "title": "采样频率", // "desc": "采样频率", // "type": "int", // "ui-pos": 23, // "auth": 0, // "size": 4, // "cur": 256, // "default": 256 // }, // "expo-fb": { // "cat": "none", // "group": "CIS", // "title": "曝光度(正面蓝色通道)", // "desc": "正面蓝色通道的曝光强度", // "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": "曝光度(正面绿色通道)", // "desc": "正面绿色通道的曝光强度", // "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": "曝光度(正面红色通道)", // "desc": "正面红色通道的曝光强度", // "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": "曝光度(背面蓝色通道)", // "desc": "背面蓝色通道的曝光强度", // "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": "曝光度(背面绿色通道)", // "desc": "背面绿色通道的曝光强度", // "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": "曝光度(背面红色通道)", // "desc": "背面红色通道的曝光强度", // "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": "增益(正面)", // "desc": "正面的增益量", // "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": "增益(背面)", // "desc": "背面的增益量", // "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": "增益补偿(正面)", // "desc": "正面的增益补偿量", // "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": "增益补偿(背面)", // "desc": "背面的增益补偿量", // "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": "纸张就绪", // "desc": "纸张已经在进纸台上放置好", // "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": "双张检测", // "desc": "检测是否有两张或者多张纸同时搓进", // "type": "string", // "ui-pos": 18, // "auth": 0, // "size": 16, // "cur": "超声波", // "default": "超声波", // "range": ["超声波", "禁用"] // }, // "is-staple": { // "cat": "none", // "group": "feeder", // "title": "装订检测", // "desc": "检测是否有订书钉存在", // "type": "bool", // "fix-id": 34861, // "ui-pos": 20, // "auth": 0, // "size": 4, // "cur": true, // "default": true // }, // "motor-speed": { // "cat": "none", // "group": "feeder", // "title": "走纸速度", // "desc": "设置走纸电机的速度,张\/分(PPM)", // "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": "歪斜检测", // "desc": "检测进纸是否歪斜", // "type": "bool", // "fix-id": 34868, // "ui-pos": 22, // "auth": 0, // "size": 4, // "cur": true, // "default": true // }, // "askew-range": { // "cat": "none", // "group": "feeder", // "title": "歪斜容忍度", // "desc": "值越小,能容忍得送入文稿歪斜角度越小", // "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" // } // }