tx-gxx-linux/device/gxx-linux/scanner/scanner.cpp

1191 lines
31 KiB
C++

#include "scanner.h"
#include <iostream>
#include "motorboard.h"
#include "Capturer.h"
#include <opencv2/opencv.hpp>
#include "StopWatch.h"
#include "iimagehandler.h"
#include "applog.h"
#include "stringex.hpp"
#include "fpgacontrol.h"
#include "scannerregs.h"
#include "fpgacontrol.h"
#include "Displaydef.h"
#include "CImageMerge.h"
#include "correct_ultis.h"
#include "SysInforTool.h"
#include "MotorboardParam.h"
#include "FeedControl.h"
#include "deviceconfig.h"
#include <openssl/md5.h>
#include <openssl/aes.h>
#include <random>
#include <stdlib.h>
static const std::string loggername = "Scanner";
Scanner::Scanner(std::shared_ptr<ICapturer> capturer, std::shared_ptr<MotorBoard> mb, std::shared_ptr<WakeUp> wake)
: bMsgLoop(true),
scancount(1024),
mfpgaversion(0x00090001)
{
LOG_INIT();
this->wake = wake;
this->mb = mb;
this->capturer = capturer;
capturer->regs()->read(15, mfpgaversion);
cout << "mfpgaversion :" << mfpgaversion << endl;
SysInforTool(ScannerSysInfo()).GetSysInfo();
// threadRunMessageLoop = std::move(std::thread(&Scanner::runMessageLoop, this));
auto mb_error_call = [&](unsigned int error_code)
{
int code = 0;
LOG_TRACE(string_format("motorboard callback mb_error_call error code = %08x \n", error_code));
if (error_code & 0x2)
{
code = 2;
LOG_TRACE("callback NO FEED\n");
}
else if (error_code & 0x4)
{
code = 4;
LOG_TRACE("callback COVER OPEN\n");
}
else if (error_code & 0x8)
{
code = 0x8;
scannerinfo.FeedErrorTimes++;
LOG_TRACE("callback FEED IN ERROR\n");
}
else if (error_code & 0x10)
{
code = 0x10;
scannerinfo.JamTimes++;
LOG_TRACE("callback PAPER JAM\n");
}
else if (error_code & 0x20)
{
code = 0x20;
scannerinfo.DoubleFeedTimes++;
LOG_TRACE("callback DOUBLE FEED\n");
}
else if (error_code & 0x40)
{
code = 0x40;
LOG_TRACE("callback STABLE\n");
}
else if (error_code & 0x80)
{
code = 0x80;
LOG_TRACE("callback SKEW\n");
}
else if (error_code & 0x00010000)
{
code = 0x10000;
LOG_TRACE("callback AQUIREIMAGE TIMEOUT\n");
}
else if (error_code & 0x00020000)
{
code = 0x20000;
LOG_TRACE("callback SIZE ERROR\n");
}
mb_error_code = code;
printf("---------------mb_error_code value = %d (%d)---------------\n", error_code, error_code);
if (code != 0)
{
HGIntInfo errType = {.From = MtBoard, .Code = code};
if (imagehandler.get())
imagehandler->add_scanevent(errType);
done_scan = 1;
}
mb_error_code = error_code;
};
auto mb_scandone_call = [&]()
{
done_scan = 1;
// if(mb_error_code == 0)
// mb_error_code = 0xffffffff;
printf("motorboard callback scan_done");
// imagehandler->add_scanevent({.From = STOPSCAN, .Code = mb_error_code});
};
auto mb_osmode_call = [&](unsigned int osmode)
{
done_scan = 1;
printf("motorboard callback mb_osmode_call changed");
};
auto mb_coveropen_call = [&](bool isopen)
{
HGIntInfo errType = {.From = MtBoard, .Code = 5 - isopen};
if (imagehandler.get())
imagehandler->add_scanevent(errType);
if (isopen)
{
LOG_TRACE("cover opened \n");
done_scan = 1;
}
else
{
printf("\n cover closed ");
LOG_TRACE("cover closed \n");
}
};
auto mb_set_sleeptime_call = [&](unsigned int speedmode)
{
printf("\n mb_set_sleeptime_call val= %d ", speedmode);
switch (speedmode & 0xf000)
{
case 0xf000:
set_sleeptime(240 * 60);
break;
case 0x7000:
set_sleeptime(20 * 60);
break;
case 0xd000:
set_sleeptime(120 * 60);
break;
case 0xb000:
set_sleeptime(60 * 60);
break;
case 0x9000:
set_sleeptime(30 * 60);
break;
case 0x3000:
set_sleeptime(5 * 60);
break;
case 0x1000:
set_sleeptime(-1);
break;
case 0x5000:
set_sleeptime(10 * 60);
break;
default:
break;
}
};
auto mb_mltop_call = [&](unsigned int value)
{
if (value & 0x00080000)
is_ml_top = true; //升降台到位
};
auto mb_auto_paper = [&](unsigned int value)
{
printf("连续扫描模式检测到有纸");
if (fu_runscan && fu_runscan->is_runing())
return;
start_scan();
};
MotorBoardGlue mb_glue = {mb_error_call, mb_scandone_call, mb_osmode_call, mb_set_sleeptime_call, mb_mltop_call, mb_auto_paper, mb_coveropen_call};
mb->set_callbacks(mb_glue);
mb->PutMsg(DisType::Dis_Idel, 0, ClearScreen::All);
scannerinfo = getscannerinfo();
auto capturecallback = [&](int cap_call_code, std::string s_info)
{
HGIntInfo info = {.From = AutoCorrect, .Code = cap_call_code, .Img_Index = s_info.length()};
if (imagehandler.get())
imagehandler->add_scanevent(info);
if (s_info.length() > 0)
((ScannerRegAccess *)m_parent)->write_info(s_info);
};
this->capturer->setcapturecall(capturecallback);
mb->set_auto_paper(false, false); //防止程序异常死掉后未关闭连续扫描导致升降台抬升扫描
mb->setautopaperkeystopcallback([&]{
if (m_config.g200params.is_autopaper)
imagehandler ? imagehandler->add_scanevent({.From = STOPSCAN, 1}) : void(0);
handstop = true; });
// mb->set_speed_mode(2);
u32 value;
mb->read(0x00, value);
printf("mb reg[0] = %d \n", value);
value = 0;
mb->read(0x03, value);
mbversion = std::to_string(value);
printf("mb reg[3] = %d \n", value);
}
Scanner::~Scanner()
{
bMsgLoop = false;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
sysEvent.Put(ScanEvent::S_EVT_STOP_SCAN);
if (threadRunMessageLoop.joinable())
threadRunMessageLoop.join();
}
std::string Scanner::getmbversion()
{
u32 value = 0;
mb->read(0x03, value);
mbversion = std::to_string(value);
return mbversion;
}
void Scanner::startcapimage(bool value)
{
FILE *fp = fopen("/sys/class/tty/ttyUSB0/device/huagao_scanner", "w");
if (fp == NULL)
perror("startcapimage open filed");
else
{
fprintf(fp, "%d", value ? 1 : 0);
fclose(fp);
}
}
bool Scanner::getcapimageflag()
{
int ret = 1;
FILE *fp = fopen("/sys/class/tty/ttyUSB0/device/huagao_scanner", "r");
if (fp == NULL)
perror("startcapimage open filed");
else
{
fscanf(fp, "%d", &ret);
fclose(fp);
}
printf("\ngetcapimageflag %d", ret);
return ret == 0 ? false : true;
}
void Scanner::add_scansever(HGIntInfo event)
{
if (imagehandler.get())
imagehandler->add_scanevent(event);
}
bool Scanner::set_hgimgconfig(GScanCap config)
{
printf("enter config set_hgimgconfig \n");
scancount = /*config.is_duplex ? config.scannum / 2 :*/ config.scannum;
m_cap = config;
if (config.resolution_dst < 300)
m_config.g200params.dpi = 1;
else if (config.resolution_dst < 500)
m_config.g200params.dpi = 2;
else
m_config.g200params.dpi = 3;
if(config.HsvFilterType!=0 || config.filter!=3 ||config.fadeback!=0)
m_config.g200params.color = 1;
printf("\n m_config.g200params.dpi =%d", m_config.g200params.dpi);
imagehandler->set_scanconfig(m_config);
if (config.is_autocrop && (config.papertype == 0) && m_config.g200params.en_autosize)
m_config.g200params.paper = 16;
if (config.papertype == 54)
m_config.g200params.paper = m_config.g200params.en_autosize ? 16 : 17;
if (config.papertype == 52 || config.papertype == 131)
m_config.g200params.paper = m_config.g200params.en_autosize ? 16 : 18;
printf("\n ********m_config.g200params.paper %d", m_config.g200params.paper);
if (imagehandler.get())
{
imagehandler->clear();
return imagehandler->set_config(config);
}
printf("\n done setting set_hgimgconfig");
return false;
}
void Scanner::configparam(HGScanConfig config)
{
LOG_TRACE(string_format("******HGScanConfig******\n config.g200params.color = %d \n config.g200params.dpi = %d \n config.g200params.paper =%d \n config.g200params.double_feed_enbale = %d \n config.g200params.stable_enbale = %d \n config.g200params.iscorrect_mode = %d \n config.g200params.pc_correct = %d\n ",
config.g200params.color,
config.g200params.dpi,
config.g200params.paper,
config.g200params.double_feed_enbale,
config.g200params.stable_enbale,
config.g200params.iscorrect_mode,
config.g200params.pc_correct));
printf("******HGScanConfig******\n config.g200params.color = %d \n config.g200params.dpi = %d \n config.g200params.paper =%d \n config.g200params.double_feed_enbale = %d \n config.g200params.stable_enbale = %d \n config.g200params.iscorrect_mode = %d \n config.g200params.pc_correct = %d\n ",
config.g200params.color,
config.g200params.dpi,
config.g200params.paper,
config.g200params.double_feed_enbale,
config.g200params.stable_enbale,
config.g200params.iscorrect_mode,
config.g200params.pc_correct);
imagehandler->set_scanconfig(config);
m_config = config;
if (config.g200params.iscorrect_mode)
{
scancount = 65535;
}
printf("\nconfigparam done\n");
}
void Scanner::try_scan(const std::string encodehexstr)
{
bool is_scan = true;
printf("\n encodehexstr = ");
for(int i =0;i<encodehexstr.length();i++)
printf(" %x",encodehexstr[i]);
if(DeviceConfig().GetParam().is_lock)
{
auto tmp_token = DeviceConfig().GetParam().token;
if((encodehexstr.length() != 32) || (tmp_token.length() !=32))
is_scan = false;
else{
AES_KEY aes_key;
std::uint8_t key[16] ={0};
//tmp_token = "C34E58CD5F3F2FF703E1AA24892FBD69";
printf("tmp_token %s",tmp_token);
for(int i =0;i<16;i++)
{
key[i] = std::strtol(tmp_token.substr(i*2,2).c_str(),nullptr,16);
}
if(AES_set_decrypt_key(key,128,&aes_key)< 0)
{
is_scan = false;
}
std::uint8_t cipher[16] ={0};
std::uint8_t decode[16] ={0};
for(int i =0;i<16;i++)
{
cipher[i] = std::strtol(encodehexstr.substr(i*2,2).c_str(),nullptr,16);
}
AES_ecb_encrypt(cipher,decode,&aes_key,AES_DECRYPT);
for(int i =0;i<scannerinfo.SerialNum.length();i++)
{
if(decode[i]!= scannerinfo.SerialNum[i])
{
is_scan = false;
break;
}
if(i == (scannerinfo.SerialNum.length() - 1 ))
is_scan = true;
}
printf("\n decode %s",(char*)decode);
}
}
if(is_scan)
start_scan();
else
{
imagehandler->add_scanevent({.From = MtBoard, 0x100});
if (m_config.g200params.is_autopaper)
imagehandler->add_scanevent({.From = STOPSCAN, 1});
imagehandler->add_scanevent({.From = STOPSCAN, 0});
mb->PutMsg(DisType::Dis_Device_Lock, 0, ClearScreen::All);
}
}
void Scanner::start_scan()
{
printf("\n ------------------m_config.g200params.paper %d", m_config.g200params.paper);
LOG_TRACE("\n ------------------start_scan------------------ \n");
capturer->regs()->read(15, mfpgaversion);
cout << "start_scan mfpgaversion :" << mfpgaversion << endl;
if (m_capturereload && m_capturereload->is_runing())
{
while (m_capturereload->is_runing())
std::this_thread::sleep_for(std::chrono::milliseconds(10));
m_capturereload.reset();
}
if (fu_runscan && fu_runscan->is_runing())
{
if (m_config.g200params.is_autopaper)
imagehandler->add_scanevent({.From = STOPSCAN, 1});
return;
}
if (wake.get())
wake->setsleepfalg(true);
mb->SetKeyState(true);
is_ml_top = handstop = false;
mb_error_code = 0;
FPGAConfigParam fpgaparam = GetFpgaparam(m_config.g200params.dpi, m_config.g200params.color);
capturer->open(m_config,fpgaparam);
if (m_config.g200params.is_autopaper)
scancount = 65536;
unsigned int reg0;
mb->read(0x00, reg0);
SMBCONFIG *smb_config = (SMBCONFIG *)&reg0;
smb_config->dpi_mode = m_config.g200params.dpi -1;
printf(" \n smb_config->dpi_mode =%d ", smb_config->dpi_mode);
mb->write(0x00, reg0);
scannerinfo = getscannerinfo();
imagehandler->Set_ratio(fpgaparam.HRatio, fpgaparam.VRatio);
int spdmode = 0;
if (scannerSp.count((SpeedMode)scannerinfo.speedmode) <= 0)
{
#ifdef G200
spdmode = 0x00; // 100ppm
#else
spdmode = 0x01; // 70ppm
#endif
}
else
spdmode = scannerSp[(SpeedMode)scannerinfo.speedmode].motorSpeed;
mb->set_speed_mode(spdmode);
printf("set speedmode %d read speedmode %d \n", spdmode, mb->get_speed_mode());
// capturer->open();
imagehandler->resetimgstatus();
mb->clear_error();
fu_runscan.reset(new ThreadEx(&Scanner::runScan, this));
}
void Scanner::stop_scan()
{
handstop = true;
printf("\n hand stop scan");
mb->stop();
if (m_config.g200params.is_autopaper == 1)
mb->set_auto_paper(false, false);
}
int Scanner::count()
{
return mb->paper_counter();
}
int Scanner::mode()
{
return mb->os_mode();
}
int Scanner::getimageprocedone()
{
if (imagehandler.get())
return imagehandler->done();
return true;
}
int Scanner::getmbstatus()
{
mb->clear_error();
uint val = 0;
mb->read(0x01, val);
printf("\n scan stop code =%d ", val & 0x700fe);
return val & 0x700fe;
}
void Scanner::test_autocorrect(int colormode)
{
printf("color mode =%s \n", colormode == 1 ? "COLOR" : "GRAY");
capturer->init_autocorrect(colormode);
}
bool Scanner::is_runscan()
{
return (imagehandler && !imagehandler->done());
// return (fu_runscan && fu_runscan->is_runing()) || (imagehandler && !imagehandler->done());
}
void Scanner::set_imagehandler(std::shared_ptr<IImageHandler> handler)
{
imagehandler.reset();
imagehandler = handler;
}
void Scanner::clear_error()
{
mb->clear_error();
}
void Scanner::runMessageLoop()
{
FsmState *fsmState = FsmStateManagerEx<InitState>::GetState();
FsmState::setScanner(this);
do
{
ScanEvent evt = sysEvent.Take();
fsmState = fsmState->on_event(evt);
} while (bMsgLoop);
}
bool Scanner::paper_ready()
{
return mb->paper_ready();
}
bool Scanner::get_keeplastpaper()
{
return mb->get_keeplastpaper();
}
void Scanner::testRunscan()
{
for (;;)
{
if (done_scan)
break;
FPGAConfigParam fpgaparam = GetFpgaparam(m_config.g200params.dpi, m_config.g200params.color);
capturer->open(m_config,fpgaparam);
int ch = 0;
int ixx = 0;
// std::cout << "mod1:" << CV_8UC3 << " " << CV_8UC1 << std::endl;
StopWatch sw;
std::this_thread::sleep_for(std::chrono::milliseconds(50));
for (int i = 0; i < 150; i++)
{
capturer->snap();
std::random_device rd; // obtain a random number from hardware
std::mt19937 gen(rd()); // seed the generator
std::uniform_int_distribution<> distr(150, 300); // define the range
std::this_thread::sleep_for(std::chrono::milliseconds(distr(gen)));
int channel = capturer->color() == 16 ? 3 : 1;
int dstwith = capturer->width() * 2 * 3 * channel;
// int dstHeight = m_config.g200params.paper == (unsigned int)PaperSize::G400_AUTO ? height : height / channel;
int dstHeight = capturer->getautosizeheight();
static int scannum = 0;
void *data;
if (data = capturer->readFrame(5000))
{
printf("\n+++++ readFrame:%fms+++++++++++\n", sw.elapsed_ms());
if (imagehandler)
{
imagehandler->add_image(data, dstwith, dstHeight, capturer->color(), scannum,mfpgaversion);
}
}
else
{
printf("\n+++++ error readFrame:%fms+++++++++++\n", sw.elapsed_ms());
}
}
capturer->close();
}
imagehandler->add_scanevent({.From = STOPSCAN, 0});
}
void Scanner::runScan()
{
// system("sudo cpufreq-set -g performance");
system("echo performance > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor");
LOG_TRACE("+++++++scanner runinng+++++++++++++\n");
if(ExceptionCheck())
{
printf("first page pick paper \n");
startcapimage(true);
mb->pick_paper();
{
done_scan = 0;
printf("set scancount %d\n", scancount);
mb->PutMsg(DisType::Dis_Scan, 0, ClearScreen::All);
mb->PutMsg(DisType::Dis_Scan_Page, mb->paper_counter(), ClearScreen::BOT);
if (m_config.g200params.is_fixedpaper || m_config.g200params.paper != (uint)PaperSize::G400_AUTO)
fixedsizescan();
else
autosizescan();
savescannerinfo(scannerinfo);
imagehandler->add_scanevent({.From = STOPSCAN, .Code = mb_error_code});
while (!imagehandler->done())
this_thread::sleep_for(chrono::milliseconds(10));
printf("\nscan finished.\n");
done_scan = 0;
if (wake.get())
{
wake->resettime();
wake->setsleepfalg(false);
}
system("sudo cpufreq-set -g ondemand");
// system("sudo echo ondemand > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor");
}
}
mb->SetKeyState(false);
m_capturereload.reset(new ThreadEx([&]{
capturer->stop();
capturer->close();
capturer->reset(); }));
if ((((mb_error_code != 0) && (mb_error_code != 0xffffffff)) || imagehandler->getimgstatus().status != NO_error) && m_config.g200params.is_autopaper)
mb->set_auto_paper(false, false);
mb->startcapimage(false);
// imagehandler->add_scanevent({.From = STOPSCAN, 0});
ControlFeedMode();
printf("-------scanner done-------\n");
}
bool Scanner::ExceptionCheck()
{
bool ret = true;
unsigned int val;
mb->start(m_config);
mb->read(0x01, val);
if ((val & 0x700fe) > 0)
{
ret = false;
if ((val & 0x700fe) == 0x14)
{
imagehandler->add_scanevent({.From = MtBoard, .Code = 4});
LOG_TRACE("\nCover Open status");
imagehandler->add_scanevent({.From = STOPSCAN, 0});
}
imagehandler->add_scanevent({.From = MtBoard, .Code = val & 0x700fe});
if (m_config.g200params.is_autopaper)
{
imagehandler->add_scanevent({.From = STOPSCAN, 1});
mb->set_auto_paper(false, false);
}
mb->errormsg(val & 0x1c003fa);
printf("\n scan stop code =%d ", val & 0x700fe);
}
#ifdef G200
StopWatch top_wh;
while (top_wh.elapsed_s() < 10)
{
if (is_ml_top || mb_error_code || handstop)
break;
this_thread::sleep_for(chrono::milliseconds(1));
}
if (!is_ml_top || mb_error_code || handstop)
{
ret = false;
if (mb_error_code == 0 && handstop == 0) // 无其他异常时,发送升降台未到达指定位置异常
{
imagehandler->add_scanevent({.From = MtBoard, 0x80000});
if (m_config.g200params.is_autopaper)
mb->set_auto_paper(false, false);
}
if (mb_error_code && m_config.g200params.is_autopaper)
mb->set_auto_paper(false, false);
this_thread::sleep_for(chrono::milliseconds(20));
imagehandler->add_scanevent({.From = STOPSCAN, 0});
if (wake.get())
{
wake->resettime();
wake->setsleepfalg(false);
}
}
LOG_TRACE(string_format("waiting paper wait_arrival_top time = %0.2f ", top_wh.elapsed_ms()));
#endif
return ret;
}
void Scanner::ControlFeedMode(){
MotorboardParam::MBParam mbparam_tmp = MotorboardParam().GetParam();
if (mbparam_tmp.automaticcontrolfeedmode)
{
printf("\n+++++++++ automaticcontrolfeedmode ");
MotorSessionInfo::MBTaskRecordInfo info_tmp{0};
if (mb_error_code == 0)
info_tmp.NormalDone = true;
if (mb_error_code == 0x8)
info_tmp.FeedError = true;
if (mb_error_code == 0x10)
info_tmp.Jammed = true;
if (mb_error_code == 0x20)
info_tmp.DoubleFeed = true;
info_tmp.CurrentScaned = scannum;
FeedControl feedcontrol_tmp;
feedcontrol_tmp.AppendPattern(info_tmp);
switch (feedcontrol_tmp.GetPredictFeedMode())
{
case FeedControl::FeedMode::FMode_Low:
setfeedmode(0);
break;
case FeedControl::FeedMode::FMode_Mid:
setfeedmode(1);
break;
case FeedControl::FeedMode::FMode_High:
setfeedmode(2);
break;
}
}
}
bool Scanner::pickpaper()
{
if (done_scan)
return false;
if (imagehandler)
{
while (imagehandler->is_limit())
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
unsigned int reg2v;
mb->read(0x02, reg2v);
if (reg2v & 0x00010000)
{ //有纸
printf("\n+++++++++pick paper ");
mb->pick_paper();
startcapimage(true);
return true;
}
else
{
printf("\n+++++++++pick paper no paper");
return false;
}
}
void Scanner::set_motorboardcallback(MotorBoardGlue glue)
{
mb->set_callbacks(glue);
}
void Scanner::set_imgprocparams(HGImgProcParms params)
{
imagehandler->config_procparams(params);
}
void Scanner::test_cap(HGScanConfig config)
{
printf("capturer openning \n");
FPGAConfigParam fpgaparam = GetFpgaparam(m_config.g200params.dpi, m_config.g200params.color);
capturer->open(config,fpgaparam);
capturer->snap();
void *data;
if (data = capturer->readFrame(2000))
{
int imtype = capturer->color() ? CV_8UC3 : CV_8UC1;
cv::Mat mat;
cv::Mat saveMat;
std::vector<cv::Mat> ch_mats;
int dstwidth, dstheight;
int width = capturer->width();
int height = capturer->height();
dstwidth = width * 3;
dstheight = height / 3;
if (imtype == CV_8UC3)
{
mat = cv::Mat(height / 3, width * 9, CV_8UC1, data);
saveMat = cv::Mat(dstheight, dstwidth, CV_8UC3);
}
else
{ // gray
saveMat = cv::Mat(height, width * 3, CV_8UC1, data);
}
static int savenum;
if (imtype == CV_8UC3)
{
for (int i = 0; i < 3; i++)
{ // B G R
cv::Mat mattemp = mat(cv::Rect(dstwidth * i, 0, dstwidth, dstheight));
ch_mats.push_back(mattemp);
}
swap(ch_mats[1], ch_mats[2]);
cv::merge(ch_mats, saveMat);
}
cv::imwrite(std::to_string(++savenum) + ".jpg", saveMat);
}
else
{
printf("LOST Image \n");
}
capturer->close();
printf("capturer closed \n");
}
void Scanner::set_sleeptime(int val)
{
if (wake.get())
wake->settime(val);
}
int Scanner::get_sleeptime()
{
if (wake.get())
return wake->gettime();
return 0;
}
void Scanner::resettime()
{
if (wake.get())
wake->resettime();
}
int Scanner::get_sleepstatus()
{
if (wake.get())
return wake->get_status();
return 0;
}
void Scanner::set_paprent(void *parent)
{
if (parent)
m_parent = parent;
}
void Scanner::settrayposition(int value)
{
printf("\n Scanner settrayposition %d", value);
if (mb.get())
{
uint val = 0;
mb->read(6, val);
auto tmp = *(SMB_FUNC *)&val;
tmp.param.lift_init_set = value;
mb->write(6, tmp.value);
printf("\n Scanner settrayposition mbvalue %d", tmp.value);
MotorboardParam().GetOrSetTrayPosition(false, value);
}
}
void Scanner::setfeedmode(int value)
{
printf("\n Scanner setfeedmode %d", value);
if (mb.get())
{
uint val = 0;
mb->read(6, val);
auto tmp = *(SMB_FUNC *)&val;
switch (value)
{
case 0:
tmp.param.func_feed_low = 1;
tmp.param.func_feed_high = tmp.param.func_feed_mid = 0;
break;
case 1:
tmp.param.func_feed_mid = 1;
tmp.param.func_feed_high = tmp.param.func_feed_low = 0;
break;
case 2:
tmp.param.func_feed_high = 1;
tmp.param.func_feed_mid = tmp.param.func_feed_low = 0;
break;
default:
tmp.param.func_feed_mid = 1;
tmp.param.func_feed_high = tmp.param.func_feed_low = 0;
break;
}
mb->write(6, tmp.value);
printf("\n Scanner setfeedmode mbvalue %d", tmp.value);
MotorboardParam().GetOrSetFeedMode(false, value);
}
}
void Scanner::set_sleepstatus(bool off)
{
if (wake.get())
{
if (off)
wake->power_on();
else
wake->power_off();
}
}
bool Scanner::getpaperon()
{
//#ifdef G200
if (mb.get())
{
uint val = 0;
mb->read(2, val);
if ((val & 0x10000) && m_config.g200params.is_autopaper)
mb->set_auto_paper(false, false);
return val & 0x10000;
}
return 0;
// #endif
// return 1;
}
void Scanner::autosizescan()
{
void *data = NULL;
scannum = 0;
StopWatch sw, swCap;
for (;;)
{
LOG_TRACE("waiting paper");
if (!done_scan) //&& mb->wait_paper_in(10000)
{
printf("waiting paper");
if (int ret = waitpaperout())
{
printf("\n waitpaperout %d ", ret);
{
if ((scancount <= (++scannum)))
{
done_scan = 1;
mb->stop();
}
if (mb_error_code != 0)
{
printf("\n wait paperout mb_error_code break");
if (!(m_cap.isuploadexceptionimage && (mb_error_code & 0x20) == 0x20))
break;
else
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
}
if (ret == 3)
{
done_scan = true;
printf("\n wait paperout return 3 break");
break;
}
scannerinfo.RollerNum++;
scannerinfo.TotalScanned++;
if (ret == 2)
{
mb->stop();
done_scan = true;
imagehandler->add_scanevent({.From = MtBoard, .Code = 0x10000});
this_thread::sleep_for(chrono::milliseconds(100));
imagehandler->add_scanevent({.From = MtBoard, .Code = 0x40000});
printf("\n paper with Hole stop ");
}
if (getcapimageflag())
{
mb->stop();
done_scan = true;
imagehandler->add_scanevent({.From = MtBoard, .Code = 0x10000});
this_thread::sleep_for(chrono::milliseconds(100));
imagehandler->add_scanevent({.From = MtBoard, .Code = 0x40000});
break;
}
}
uint height = 0;
if (m_config.g200params.paper == (unsigned int)PaperSize::G400_AUTO)
{
capturer->regs()->read(0x14,height);
if(height < 1000 )
std::this_thread::sleep_for(std::chrono::milliseconds((1000 - height)/70));
int delaytime = m_config.g200params.dpi == 0x02 ? 100 : (m_config.g200params.dpi == 0x03 ? 250 : 30);
this_thread::sleep_for(chrono::milliseconds(delaytime)); //纸张过了 多采集几张
height = capturer->getautosizeheight();
}
else
{
#ifdef G200
int delaytime = m_config.g200params.dpi == 0x02 ? 60 : (m_config.g200params.dpi == 0x03 ? 170 : 27);
#else
int delaytime = m_config.g200params.dpi == 0x02 ? 100 : (m_config.g200params.dpi == 0x03 ? 250 : 50);
#endif
this_thread::sleep_for(chrono::milliseconds(delaytime)); //纸张过了 多采集几张
height = capturer->getautosizeheight();
}
if (height)
{
if (!(m_cap.is_dogeardetection || m_cap.en_sizecheck))
{
if (!pickpaper())
done_scan = 1;
}
int channel = capturer->color() == 16 ? 3 : 1;
int dstwith = capturer->width() * 2 * 3 * channel;
// int dstHeight = m_config.g200params.paper == (unsigned int)PaperSize::G400_AUTO ? height : height / channel;
int dstHeight = height;
printf("\ndstwith =%d dstHeight = %d scancount %d", dstwith, dstHeight, scannum);
swCap.reset();
if (data = capturer->readFrame(10000))
{
printf("\n+++++ readFrame:%fms+++++++++++\n", sw.elapsed_ms());
if (imagehandler)
{
imagehandler->add_image(data, dstwith, dstHeight, capturer->color(), scannum,mfpgaversion);
data = NULL;
}
if (m_cap.is_dogeardetection || m_cap.en_sizecheck)
{
if (imagehandler->getimgstatus().status != NO_error)
{
printf("\n+++++ status :%d ms+++++++++++\n", imagehandler->getimgstatus().status);
mb->stop();
done_scan = 1;
switch (imagehandler->getimgstatus().status)
{
case Error_Status::Dog_error:
mb->PutMsg(DisType::Dis_Err_DogEar, 0, ClearScreen::All);
break;
case Error_Status::Size_error:
mb->PutMsg(DisType::Dis_Err_Size, 0, ClearScreen::All);
break;
default:
break;
}
}
else
{
if (!pickpaper())
done_scan = 1;
}
}
printf("\n+++++ addimage:%fms+++++++++++\n", sw.elapsed_ms());
LOG_TRACE(string_format("capture one=%fms", swCap.elapsed_ms()));
}
else
{
imagehandler->add_scanevent({.From = V4L2, .Code = 0});
done_scan = true;
LOG_TRACE("capture error");
printf("capture error \n");
}
}
}
else
{
if (!done_scan)
{
uint value = 0;
mb->read(0x2, value);
if (!(value & 0x20000)) // bit 17 scandone
{
printf("mb 02 reg value =%d \n", value);
done_scan = 1;
LOG_TRACE("---------Time out-----");
break;
}
else
{
mb->stop();
done_scan = true;
imagehandler->add_scanevent({.From = MtBoard, .Code = 0x10000});
printf("\n time out ");
break;
}
}
}
}
else
{
printf("\n done scan break");
break;
}
}
}
void Scanner::fixedsizescan()
{
void *data = NULL;
scannum = 0;
StopWatch sw;
StopWatch swCap;
for (;;)
{
LOG_TRACE("waiting paper");
if (!done_scan) //&& mb->wait_paper_in(10000)
{
// capturer->snap();
printf("waiting paper...\n");
int timedelay = m_config.g200params.dpi == 0x02 ? 25 : (m_config.g200params.dpi == 0x03 ? 35 : 15);
this_thread::sleep_for(chrono::milliseconds(timedelay)); //纸张过了 多采集几张
if (mb->wait_paper_out(10000))
{
if ((scancount <= (++scannum)))
{
done_scan = 1;
mb->stop();
}
if (mb_error_code != 0)
{
printf("\n +++++ mb_error_code =%d ++++++", mb_error_code);
if (!(m_cap.isuploadexceptionimage && (mb_error_code & 0x20) == 0x20))
break;
}
uint height;
if (m_config.g200params.paper == (unsigned int)PaperSize::G400_AUTO)
{
capturer->regs()->read(0x14,height);
if(height < 1000 )
std::this_thread::sleep_for(std::chrono::milliseconds((1000 - height)/70));
int delaytime = m_config.g200params.dpi == 0x02 ? 100 : (m_config.g200params.dpi == 0x03 ? 250 : 50);
this_thread::sleep_for(chrono::milliseconds(delaytime)); //纸张过了 多采集几张
height = capturer->getautosizeheight();
printf("\n+++++ getautosizeheights+++++++++++\n");
}
else
{
height = capturer->height();
printf("\n+++++ height+++++++++++\n");
}
if (height)
{
int channel = capturer->color() == 16 ? 3 : 1;
int dstwith = capturer->width() * 2 * 3 * channel;
int dstHeight = m_config.g200params.paper == (unsigned int)PaperSize::G400_AUTO ? height : height / channel;
// int dstHeight = height;
printf("\ndstwith =%d dstHeight = %d scancount %d", dstwith, dstHeight, scannum);
if (data = capturer->readFrame(10000))
{
printf("\n+++++ readFrame:%fms+++++++++++\n", sw.elapsed_ms());
if (imagehandler)
{
imagehandler->add_image(data, dstwith, dstHeight, capturer->color(), scannum,mfpgaversion);
data = NULL;
}
if (imagehandler->getimgstatus().status != NO_error)
{
printf("\n+++++ status :%d ms+++++++++++\n", imagehandler->getimgstatus().status);
mb->stop();
done_scan = 1;
switch (imagehandler->getimgstatus().status)
{
case Error_Status::Dog_error:
mb->PutMsg(DisType::Dis_Err_DogEar, 0, ClearScreen::All);
break;
case Error_Status::Size_error:
mb->PutMsg(DisType::Dis_Err_Size, 0, ClearScreen::All);
break;
default:
break;
}
}
else
{
if (!pickpaper())
done_scan = 1;
}
printf("\n+++++ addimage:%fms+++++++++++\n", sw.elapsed_ms());
scannerinfo.RollerNum++;
scannerinfo.TotalScanned++;
}
else
{
imagehandler->add_scanevent({.From = V4L2, .Code = 0});
done_scan = true;
LOG_TRACE("capture error");
printf("capture error \n");
}
}
}
else
{
if (!done_scan)
{
uint value = 0;
mb->read(0x2, value);
if (!(value & 0x20000)) // bit 17 scandone
{
printf("mb 02 reg value =%d \n", value);
done_scan = 1;
LOG_TRACE("---------Time out-----");
break;
}
}
}
}
else
{
break;
}
}
}
void Scanner::clean_paper_road()
{
if(mb.get())
mb->clean_paper_road();
}
int Scanner::waitpaperout()
{
if (mb->wait_paper_out(10000)) //10秒内收到正常翻转信号或者异常时 返回 1 继续扫描
return 1;
uint reg0,reg14;
reg0 = reg14 =0;
capturer->regs()->read(14, reg14);
capturer->regs()->read(0, reg0);
if(m_config.g200params.color)
reg14 *=3;
printf("\n wait paperout reg14 =%d reg0 =%d",reg14,reg0);
if ((reg14 & 0xffff) == 0) // 未收到异常与翻转信号 返回 0 退出扫描
return 0;
// if(handstop && (capturer->regs()->read(14,val)&0xffff) > 0)
if (handstop) //pc手动停止时返回 3 退出扫描流程 不进行标位置回读和计数累加
return 3;
if ((reg14 & 0xffff) == (reg0 & 0xffff))
return mb_error_code == 0 ? 2 : 0; // 无异常有图像时 返回2 读取图像数据 防止丢图
return 0;
}