newtx/hardware/hardware.h

561 lines
13 KiB
C
Raw Normal View History

// 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;
class GVideoISP1;
class MotorBoard;
class scanner_hw : public sane_opt_provider
{
2023-12-29 02:53:04 +00:00
std::function<IMAGE_HANDLER_PROTO> img_handler_ = std::function<IMAGE_HANDLER_PROTO>();
2023-12-19 09:11:41 +00:00
bool scanning_ = false;
int time_to_exit_auto_scan_ = 60; // seconds
std::unique_ptr<FpgaComm> img_controller_;
std::unique_ptr<GVideoISP1> camera_;
std::unique_ptr<MotorBoard> motor_;
2023-12-29 02:53:04 +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_;
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<std::string, std::function<void(void*)>> opt_handler_;
void init(void);
void thread_image_capture(void);
bool is_scan_fatal(void);
2024-01-03 09:39:16 +00:00
void retrieve_v4l2_mem(safe_fifo<int>* mem, int* used);
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": "颜色模式",
// "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",
2023-12-19 09:11:41 +00:00
// "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",
2023-12-19 09:11:41 +00:00
// "ui-pos": 21,
// "auth": 0,
// "unit": "microsec",
// "size": 4,
// "cur": 1000,
// "default": 1000
// },
// "frame-h": {
// "cat": "none",
// "group": "CIS",
// "title": "帧高度",
// "desc": "采集头每一帧的采集高度",
// "type": "int",
2023-12-19 09:11:41 +00:00
// "ui-pos": 22,
// "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,
// "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",
2023-12-19 09:11:41 +00:00
// "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",
2023-12-19 09:11:41 +00:00
// "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",
2023-12-19 09:11:41 +00:00
// "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",
2023-12-19 09:11:41 +00:00
// "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",
2023-12-19 09:11:41 +00:00
// "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",
2023-12-19 09:11:41 +00:00
// "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
2023-12-29 02:53:04 +00:00
// },
// "askew-range": {
// "cat": "none",
// "group": "feeder",
// "title": "歪斜容忍度",
// "desc": "值越小,能容忍得送入文稿歪斜角度越小",
// "type": "int",
// "fix-id": 34869,
// "ui-pos": 23,
2023-12-29 02:53:04 +00:00
// "auth": 0,
// "size": 4,
// "cur": 3,
// "default": 3,
// "range": {
// "min": 1,
// "max": 7,
// "step": 1
// },
// "depend": "is-check-askew==true"
// }
2024-01-03 09:39:16 +00:00
// }