2023-12-19 07:27:16 +00:00
|
|
|
|
// hardware drivers
|
|
|
|
|
//
|
|
|
|
|
// Contains: CIS, MotorBoard, ...
|
|
|
|
|
//
|
|
|
|
|
// Date: 2023-12-18
|
|
|
|
|
|
|
|
|
|
#include <sane_opt_json/base_opt.h>
|
|
|
|
|
#include <functional>
|
|
|
|
|
#include <base/packet.h>
|
|
|
|
|
#include <base/data.h>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
|
|
// 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;
|
2023-12-20 07:23:24 +00:00
|
|
|
|
class GVideoISP1;
|
|
|
|
|
class MotorBoard;
|
2023-12-19 07:27:16 +00:00
|
|
|
|
|
|
|
|
|
class scanner_hw : public sane_opt_provider
|
|
|
|
|
{
|
|
|
|
|
std::function<IMAGE_HANDLER_PROTO> img_handler_;
|
2023-12-19 09:11:41 +00:00
|
|
|
|
bool scanning_ = false;
|
|
|
|
|
bool auto_scan_ = false;
|
|
|
|
|
int time_to_exit_auto_scan_ = 60; // seconds
|
|
|
|
|
std::unique_ptr<FpgaComm> img_controller_;
|
2023-12-20 07:23:24 +00:00
|
|
|
|
std::unique_ptr<GVideoISP1> camera_;
|
|
|
|
|
std::unique_ptr<MotorBoard> motor_;
|
2023-12-19 07:27:16 +00:00
|
|
|
|
|
|
|
|
|
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_;
|
|
|
|
|
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];
|
2023-12-20 08:44:39 +00:00
|
|
|
|
|
|
|
|
|
bool staple_chk_ = true;
|
|
|
|
|
bool screw_chk_ = true;
|
|
|
|
|
bool paper_on_ = false;
|
|
|
|
|
bool double_chk_ = true;
|
|
|
|
|
int motor_speed_ = /*SPEED_PPM_100*/0;
|
2023-12-19 07:27:16 +00:00
|
|
|
|
std::map<std::string, std::function<void(void*)>> opt_handler_;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void init(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_PROTO> image_handler);
|
|
|
|
|
int start_scan(void);
|
|
|
|
|
int stop_scan(void);
|
|
|
|
|
int close(void);
|
|
|
|
|
};
|
|
|
|
|
// {
|
|
|
|
|
// "mode": {
|
|
|
|
|
// "cat": "none",
|
|
|
|
|
// "group": "CIS",
|
|
|
|
|
// "title": "颜色模式",
|
2023-12-20 08:44:39 +00:00
|
|
|
|
// "desc": "选择镜头色彩工作模式",
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "type": "string",
|
|
|
|
|
// "fix-id": 34819,
|
|
|
|
|
// "ui-pos": 10,
|
|
|
|
|
// "auth": 0,
|
|
|
|
|
// "size": 12,
|
|
|
|
|
// "cur": "彩色",
|
|
|
|
|
// "default": "彩色",
|
|
|
|
|
// "range": ["彩色", "灰度"]
|
|
|
|
|
// },
|
|
|
|
|
// "resolution": {
|
|
|
|
|
// "cat": "none",
|
|
|
|
|
// "group": "CIS",
|
|
|
|
|
// "title": "分辨率",
|
2023-12-20 08:44:39 +00:00
|
|
|
|
// "desc": "设置镜头工作的分辨率",
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "type": "int",
|
|
|
|
|
// "fix-id": 34840,
|
|
|
|
|
// "ui-pos": 11,
|
|
|
|
|
// "auth": 0,
|
|
|
|
|
// "size": 4,
|
|
|
|
|
// "cur": 300,
|
|
|
|
|
// "default": 300,
|
|
|
|
|
// "range": [200, 300]
|
|
|
|
|
// },
|
2023-12-20 07:23:24 +00:00
|
|
|
|
// "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"
|
|
|
|
|
// },
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "baud": {
|
|
|
|
|
// "cat": "none",
|
|
|
|
|
// "group": "CIS",
|
|
|
|
|
// "title": "波特率",
|
|
|
|
|
// "desc": "CIS控制通信速率",
|
|
|
|
|
// "type": "int",
|
2023-12-19 09:11:41 +00:00
|
|
|
|
// "ui-pos": 20,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "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",
|
2023-12-19 09:11:41 +00:00
|
|
|
|
// "ui-pos": 21,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "auth": 0,
|
|
|
|
|
// "unit": "microsec",
|
|
|
|
|
// "size": 4,
|
|
|
|
|
// "cur": 1000,
|
|
|
|
|
// "default": 1000
|
|
|
|
|
// },
|
|
|
|
|
// "fram-h": {
|
|
|
|
|
// "cat": "none",
|
|
|
|
|
// "group": "CIS",
|
|
|
|
|
// "title": "帧高度",
|
|
|
|
|
// "desc": "采集头每一帧的采集高度",
|
|
|
|
|
// "type": "int",
|
2023-12-19 09:11:41 +00:00
|
|
|
|
// "ui-pos": 22,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "auth": 0,
|
|
|
|
|
// "size": 4,
|
|
|
|
|
// "cur": 12,
|
|
|
|
|
// "default": 12
|
|
|
|
|
// },
|
|
|
|
|
// "sample": {
|
|
|
|
|
// "cat": "none",
|
|
|
|
|
// "group": "CIS",
|
|
|
|
|
// "title": "采样频率",
|
|
|
|
|
// "desc": "采样频率",
|
|
|
|
|
// "type": "int",
|
2023-12-19 09:11:41 +00:00
|
|
|
|
// "ui-pos": 23,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "auth": 0,
|
|
|
|
|
// "size": 4,
|
|
|
|
|
// "cur": 256,
|
|
|
|
|
// "default": 256
|
|
|
|
|
// },
|
|
|
|
|
// "expo-fb": {
|
|
|
|
|
// "cat": "none",
|
|
|
|
|
// "group": "CIS",
|
|
|
|
|
// "title": "曝光度(正面蓝色通道)",
|
|
|
|
|
// "desc": "正面蓝色通道的曝光强度",
|
|
|
|
|
// "type": "int",
|
2023-12-20 07:23:24 +00:00
|
|
|
|
// "ui-pos": 32,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "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",
|
2023-12-19 09:11:41 +00:00
|
|
|
|
// "ui-pos": 31,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "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",
|
2023-12-20 07:23:24 +00:00
|
|
|
|
// "ui-pos": 30,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "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",
|
2023-12-20 07:23:24 +00:00
|
|
|
|
// "ui-pos": 35,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "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",
|
2023-12-19 09:11:41 +00:00
|
|
|
|
// "ui-pos": 34,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "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",
|
2023-12-20 07:23:24 +00:00
|
|
|
|
// "ui-pos": 33,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "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",
|
2023-12-19 09:11:41 +00:00
|
|
|
|
// "ui-pos": 40,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "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",
|
2023-12-19 09:11:41 +00:00
|
|
|
|
// "ui-pos": 41,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "auth": 0,
|
|
|
|
|
// "size": 4,
|
|
|
|
|
// "cur": 0,
|
|
|
|
|
// "default": 0,
|
|
|
|
|
// "range": {
|
|
|
|
|
// "min": -1000,
|
|
|
|
|
// "max": 1000,
|
|
|
|
|
// "step": 1
|
|
|
|
|
// }
|
|
|
|
|
// },
|
|
|
|
|
// "off-f": {
|
|
|
|
|
// "cat": "none",
|
|
|
|
|
// "group": "CIS",
|
2023-12-20 07:23:24 +00:00
|
|
|
|
// "title": "增益补偿(正面)",
|
|
|
|
|
// "desc": "正面的增益补偿量",
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "type": "int",
|
2023-12-19 09:11:41 +00:00
|
|
|
|
// "ui-pos": 45,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "auth": 0,
|
|
|
|
|
// "size": 4,
|
|
|
|
|
// "cur": 0,
|
|
|
|
|
// "default": 0,
|
|
|
|
|
// "range": {
|
2023-12-20 07:23:24 +00:00
|
|
|
|
// "min": -100,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "max": 100,
|
|
|
|
|
// "step": 1
|
|
|
|
|
// }
|
|
|
|
|
// },
|
|
|
|
|
// "off-b": {
|
|
|
|
|
// "cat": "none",
|
|
|
|
|
// "group": "CIS",
|
2023-12-20 07:23:24 +00:00
|
|
|
|
// "title": "增益补偿(背面)",
|
|
|
|
|
// "desc": "背面的增益补偿量",
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "type": "int",
|
2023-12-19 09:11:41 +00:00
|
|
|
|
// "ui-pos": 46,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "auth": 0,
|
|
|
|
|
// "size": 4,
|
|
|
|
|
// "cur": 0,
|
|
|
|
|
// "default": 0,
|
|
|
|
|
// "range": {
|
2023-12-20 07:23:24 +00:00
|
|
|
|
// "min": -100,
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// "max": 100,
|
|
|
|
|
// "step": 1
|
|
|
|
|
// }
|
2023-12-20 08:44:39 +00:00
|
|
|
|
// },
|
|
|
|
|
// "paper-on": {
|
|
|
|
|
// "cat": "none",
|
|
|
|
|
// "group": "feeder",
|
|
|
|
|
// "title": "纸张就绪",
|
|
|
|
|
// "desc": "纸张已经在进纸台上放置好",
|
|
|
|
|
// "type": "bool",
|
|
|
|
|
// "fix-id": 34912,
|
|
|
|
|
// "ui-pos": 15,
|
|
|
|
|
// "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": 16,
|
|
|
|
|
// "auth": 0,
|
|
|
|
|
// "size": 16,
|
|
|
|
|
// "cur": "超声波",
|
|
|
|
|
// "default": "超声波",
|
|
|
|
|
// "range": ["超声波", "禁用"]
|
|
|
|
|
// },
|
|
|
|
|
// "is-staple": {
|
|
|
|
|
// "cat": "none",
|
|
|
|
|
// "group": "feeder",
|
|
|
|
|
// "title": "装订检测",
|
|
|
|
|
// "desc": "检测是否有订书钉存在",
|
|
|
|
|
// "type": "bool",
|
|
|
|
|
// "fix-id": 34861,
|
|
|
|
|
// "ui-pos": 17,
|
|
|
|
|
// "auth": 0,
|
|
|
|
|
// "size": 4,
|
|
|
|
|
// "cur": true,
|
|
|
|
|
// "default": true
|
|
|
|
|
// },
|
|
|
|
|
// "motor-speed": {
|
|
|
|
|
// "cat": "none",
|
|
|
|
|
// "group": "feeder",
|
|
|
|
|
// "title": "走纸速度",
|
|
|
|
|
// "desc": "设置走纸电机的速度,张\/分(PPM)",
|
|
|
|
|
// "type": "int",
|
|
|
|
|
// "ui-pos": 18,
|
|
|
|
|
// "auth": 0,
|
|
|
|
|
// "size": 4,
|
|
|
|
|
// "cur": 100,
|
|
|
|
|
// "default": 100,
|
|
|
|
|
// "range": [70, 100, 120, 150]
|
|
|
|
|
// },
|
|
|
|
|
// "is-check-askew": {
|
|
|
|
|
// "cat": "none",
|
|
|
|
|
// "group": "feeder",
|
|
|
|
|
// "title": "歪斜检测",
|
|
|
|
|
// "desc": "检测进纸是否歪斜",
|
|
|
|
|
// "type": "bool",
|
|
|
|
|
// "fix-id": 34868,
|
|
|
|
|
// "ui-pos": 19,
|
|
|
|
|
// "auth": 0,
|
|
|
|
|
// "size": 4,
|
|
|
|
|
// "cur": true,
|
|
|
|
|
// "default": true
|
2023-12-19 07:27:16 +00:00
|
|
|
|
// }
|
|
|
|
|
// }
|