newtx/hardware/hardware.h

613 lines
14 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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>
#include <utility>
// 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 gVideo;
class MotorBoard;
class scanner_hw : public sane_opt_provider
{
std::function<IMAGE_HANDLER_PROTO> img_handler_ = std::function<IMAGE_HANDLER_PROTO>();
volatile bool scanning_ = false;
int time_to_exit_auto_scan_ = 60; // seconds
std::unique_ptr<FpgaComm> img_controller_;
std::unique_ptr<gVideo> camera_;
std::unique_ptr<MotorBoard> motor_;
std::unique_ptr<std::thread> scan_thread_;
safe_fifo<std::pair<int, int>> mb_events_;
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 cis_length_ = 3888;
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 init_version(std::string& text);
void thread_image_capture(void);
bool is_scan_fatal(void);
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);
bool is_scanning(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": "分辨<E58886><E8BEA8>?,
// "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": "启用后文稿放入扫描仪时将自动启动扫<E58AA8><E689AB>?,
// "type": "bool",
// "fix-id": 34873,
// "ui-pos": 12,
// "auth": 0,
// "size": 4,
// "cur": false,
// "default": false
// },
// "wait-scan-exit": {
// "cat": "base",
// "group": "feeder",
// "title": "待纸扫描退出时<E587BA><E697B6>?,
// "desc": "设置结束待纸扫描的时<E79A84><E697B6>?,
// "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": "选择指定数量扫描或连续扫<E7BBAD><E689AB>?,
// "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": "扫描仪自动修正分纸力<E7BAB8><E58A9B>?,
// "type": "bool",
// "fix-id": 34876,
// "ui-pos": 27,
// "auth": 0,
// "size": 4,
// "cur": false,
// "default": false
// },
// "feed-strength-value": {
// "cat": "base",
// "group": "feeder",
// "title": " 进纸失败<E5A4B1><E8B4A5>?,
// "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": "一<><E4B880>?,
// "default": "一<><E4B880>?,
// "range": ["<22><>?, "一<><E4B880>?, "<22><>?],
// "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": "不休<E4B88D><E4BC91>?,
// "default": "不休<E4B88D><E4BC91>?,
// "range": ["不休<E4B88D><E4BC91>?, "五分<E4BA94><E58886>?, "十分<E58D81><E58886>?, "半小<E58D8A><E5B08F>?, "一小时", "两小<E4B8A4><E5B08F>?, "四小<E59B9B><E5B08F>?]
// },
// "baud": {
// "cat": "none",
// "group": "CIS",
// "title": "波特<E6B3A2><E789B9>?,
// "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": "采集头接受命令后的动作延迟时<E8BF9F><E697B6>?,
// "type": "int",
// "ui-pos": 21,
// "auth": 0,
// "unit": "microsec",
// "size": 4,
// "cur": 1000,
// "default": 1000
// },
// "frame-h": {
// "cat": "none",
// "group": "CIS",
// "title": "帧高<E5B8A7><E9AB98>?,
// "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": "曝光度正面蓝色通道<E9809A><E98193>?,
// "desc": "正面蓝色通道的曝光强<E58589><E5BCBA>?,
// "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": "曝光度正面绿色通道<E9809A><E98193>?,
// "desc": "正面绿色通道的曝光强<E58589><E5BCBA>?,
// "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": "曝光度正面红色通道<E9809A><E98193>?,
// "desc": "正面红色通道的曝光强<E58589><E5BCBA>?,
// "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": "曝光度背面蓝色通道<E9809A><E98193>?,
// "desc": "背面蓝色通道的曝光强<E58589><E5BCBA>?,
// "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": "曝光度背面绿色通道<E9809A><E98193>?,
// "desc": "背面绿色通道的曝光强<E58589><E5BCBA>?,
// "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": "曝光度背面红色通道<E9809A><E98193>?,
// "desc": "背面红色通道的曝光强<E58589><E5BCBA>?,
// "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": "双张检<E5BCA0><E6A380>?,
// "desc": "检测是否有两张或者多张纸同时搓进",
// "type": "string",
// "ui-pos": 18,
// "auth": 0,
// "size": 16,
// "cur": "超声<E8B685><E5A3B0>?,
// "default": "超声<E8B685><E5A3B0>?,
// "range": ["超声<E8B685><E5A3B0>?, "禁用"]
// },
// "is-staple": {
// "cat": "none",
// "group": "feeder",
// "title": "装订检<E8AEA2><E6A380>?,
// "desc": "检测是否有订书钉存<E99289><E5AD98>?,
// "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<50><4D>?,
// "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": "歪斜检<E6969C><E6A380>?,
// "desc": "检测进纸是否歪<E590A6><E6ADAA>?,
// "type": "bool",
// "fix-id": 34868,
// "ui-pos": 22,
// "auth": 0,
// "size": 4,
// "cur": true,
// "default": true
// },
// "askew-range": {
// "cat": "none",
// "group": "feeder",
// "title": "歪斜容忍<E5AEB9><E5BF8D>?,
// "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"
// },
// "cis-len": {
// "cat": "base",
// "group": "关于",
// "title": "镜头<E9959C><E5A4B4>?,
// "desc": "图像采集镜头的长度单位为毫米mm<6D><6D>?,
// "type": "int",
// "ui-pos": 30,
// "auth": 0,
// "unit": "mm",
// "readonly": true,
// "size": 4,
// "auto": false,
// "cur": 1632,
// "default": 1632
// },
// "motor-ver": {
// "cat": "none",
// "group": "关于",
// "title": "电机驱动版本",
// "desc": "电机板驱动程序版本号",
// "type": "string",
// "fix-id": 34909,
// "ui-pos": 16,
// "auth": 0,
// "readonly": true,
// "size": 24,
// "auto": false,
// "cur": "",
// "default": ""
// },
// "fpga-ver": {
// "cat": "none",
// "group": "关于",
// "title": "CIS控制器版<E599A8><E78988>?,
// "desc": "镜头参数控制驱动程序版本<E78988><E69CAC>?,
// "type": "string",
// "ui-pos": 17,
// "auth": 0,
// "readonly": true,
// "size": 24,
// "auto": false,
// "cur": "",
// "default": ""
// }
// }