rk3399_arm_lvds/scanner/scanner.cpp

1653 lines
48 KiB
C++
Raw Permalink 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.

#include "scanner.h"
#include <iostream>
#include "motorboard.h"
#include "Capturer.h"
#include "MultiFrameCapture.h"
#include "MultiFrameCapture_8478_HL.h"
#include "MultiFrameCapture_8458Color.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 "utils.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>
#include "ContaminationDetection.h"
#include "SensorConfig.h"
#include "CameraParam.h"
#include "ThreadPool.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;
ICapturer * cap = capturer.get();
if(typeid(*cap) == typeid(MultiFrameCapture)) capturer_type = 19908478;
else if(typeid(*cap) == typeid(MultiFrameCapture_8478_HL)) capturer_type = 20038478;
else if(typeid(*cap) == typeid(MultiFrameCapture_8458Color)) capturer_type = 19908458;
else capturer_type = 0;
capturer->regs()->read(15, mfpgaversion);
cout << "mfpgaversion :" << mfpgaversion << "\t capturer_type : " << capturer_type << endl;
SysInforTool(ScannerSysInfo()).GetSysInfo();
update_disk_syslog("On initing Scanner.",true);
// threadRunMessageLoop = std::move(std::thread(&Scanner::runMessageLoop, this));
auto mb_error_call = [&](unsigned int error_code)
{
int code = 0;
img_status Img_status = img_status::IMG_STATUS_OK;
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");
update_mem_syslog("callback NO FEED",false);
}
else if (error_code & 0x4)
{
code = 4;
//LOG_TRACE("callback COVER OPEN\n");
update_mem_syslog("callback COVER OPEN",false);
}
else if (error_code & 0x8)
{
code = 0x8;
scannerinfo.FeedErrorTimes++;
//LOG_TRACE("callback FEED IN ERROR\n");
update_mem_syslog("callback FEED IN ERROR",false);
}
else if (error_code & 0x10)
{
code = 0x10;
scannerinfo.JamTimes++;
Img_status = img_status::IMG_STATUS_JAM;
//LOG_TRACE("callback PAPER JAM\n");
update_mem_syslog("callback PAPER JAM",false);
}
else if (error_code & 0x20)
{
code = 0x20;
scannerinfo.DoubleFeedTimes++;
Img_status = img_status::IMG_STATUS_DOUBLE;
//LOG_TRACE("callback DOUBLE FEED\n");
update_mem_syslog("callback DOUBLE FEED",false);
}
else if (error_code & 0x40)
{
code = 0x40;
//LOG_TRACE("callback STABLE\n");
update_mem_syslog("callback STABLE",false);
}
else if (error_code & 0x80)
{
code = 0x80;
Img_status = img_status::IMG_STATUS_STAPLE;
//LOG_TRACE("callback SKEW\n");
update_mem_syslog("callback SKEW",false);
}
else if (error_code & 0x00010000)
{
code = 0x10000;
//LOG_TRACE("callback AQUIREIMAGE TIMEOUT\n");
update_mem_syslog("callback AQUIREIMAGE TIMEOUT",false);
}
else if (error_code & 0x00020000)
{
code = 0x20000;
//LOG_TRACE("callback SIZE ERROR\n");
update_mem_syslog("callback SIZE ERROR",false);
}
mb_error_code = code;
printf("---------------mb_error_code value = %d ---------------\n", error_code);
if (code != 0)
{
HGIntInfo errType = {.From = MtBoard, .Code = code,.Img_Index = 0,.Img_Status =Img_status};
//if(!(errType.Code == 0x20 && m_config.g200params.double_feed_enbale && m_config.g200params.double_out_en))
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");
update_mem_syslog("motorboard callback scan_done",false);
};
auto mb_osmode_call = [&](unsigned int osmode)
{
done_scan = 1;
printf("motorboard callback mb_osmode_call changed");
};
auto mb_coveropen_call = [&](bool isopen)
{
if (isopen)
{
LOG_TRACE("cover opened \n");
HGIntInfo errType = {.From = MtBoard, .Code = 4};
if (imagehandler.get())
imagehandler->add_scanevent(errType);
done_scan = 1;
}
else
{
printf("\n cover closed ");
LOG_TRACE("cover closed \n");
}
update_mem_syslog(isopen?"cover opened ":"cover closed",false);
};
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([&]{
//printf(" send_scanevent() \n");
if (m_config.g200params.is_autopaper)
if(imagehandler) imagehandler->add_scanevent({.From = STOPSCAN, 1});
//printf(" handstop() \n");
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()
{
return mb->getmbversion();
}
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;
if(config.removeMorr){
if(m_config.g200params.dpi < 3) slow_moire = true;
else slow_moire = false;
config.removeMorr = 0;
}
else slow_moire = false;
if((capturer_type == 19908478 || capturer_type == 20038478) && (config.papertype == 52 || config.papertype == 54)) slow_moire = false;
if(capturer_type == 19908458) slow_moire = false;
if((config.is_autodiscradblank_normal || config.is_autodiscradblank_vince) && config.detect_size_discard_blank)
config.detect_size_discard_blank = false;
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(m_config.g200params.dpi == 1) config.maxszie_sanp_height = std::max(840u,std::min(6000u,config.maxszie_sanp_height));
else if(m_config.g200params.dpi == 2) config.maxszie_sanp_height = std::max(840u,std::min(2000u,config.maxszie_sanp_height));
else if(m_config.g200params.dpi == 3) config.maxszie_sanp_height = std::max(420u,std::min(670u,config.maxszie_sanp_height));
m_cap = config;
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(m_config.g200params.paper == 16)
// m_config.g200params.paper = 0;
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(capturer.get()) capturer->set_gscancap(m_cap);
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);
//config.g200params.double_out_en = false;
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(Get_static_deviceconfig().GetParam().is_lock)
{
auto tmp_token = Get_static_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 \n", m_config.g200params.paper);
LOG_TRACE("\n ------------------start_scan------------------ \n");
capturer->regs()->read(15, mfpgaversion);
cout << "start_scan mfpgaversion :" << mfpgaversion << endl;
getmbversion();
std::string log_str = "On starting scan with color mode = " + std::to_string(m_config.g200params.color)+
"dpi = " +std::to_string(m_config.g200params.dpi)+" paper type = "+std::to_string(m_config.g200params.paper);
update_disk_syslog(log_str,true);
update_mem_syslog(log_str,true);
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;
if(capturer_type > 0)
{
FPGAConfigParam_8478 fpgaparam = Get_Static_CorrectParam().GetFpgaparam_8478(slow_moire ? (m_config.g200params.dpi == 1? 0x10:0x11):
m_config.g200params.dpi, m_config.g200params.color);
FPGAConfigParam fpgaparam_color = Get_Static_CorrectParam().GetFpgaparam_8458_color_Lvds(slow_moire ? (m_config.g200params.dpi == 1? 0x10:0x11):
m_config.g200params.dpi, m_config.g200params.color);
if(m_cap.papertype == 52 || m_cap.papertype == 54)
{
fpgaparam = Get_Static_CorrectParam().GetFpgaparam_8478(m_config.g200params.dpi == 1? 0x20:((m_config.g200params.dpi == 2 ? 0x21 : 3)), m_config.g200params.color);
SMB_JAM_Time jam_time{0};
jam_time.param.jam_time_1 = jam_time.param.jam_time_2 = jam_time.param.jam_time_3 = jam_time.param.jam_time_4 = (m_cap.maxszie_sanp_height+17)/18;
printf("!!!!max size jam time : %d \n ",jam_time.param.jam_time_1);
mb->set_jam_param(jam_time);
mb->read(10,jam_time.value);
printf("mb ->reg 10 : 0x%x \n",jam_time.value);
}
else
mb->set_jam_param({0});
if(capturer_type == 19908458)
capturer->open(m_config,fpgaparam_color);
else
capturer->open(m_config,fpgaparam);
imagehandler->Set_ratio(fpgaparam.HRatio, fpgaparam.VRatio);
}
else
{
FPGAConfigParam fpgaparam = GetFpgaparam(slow_moire ? 0x10: m_config.g200params.dpi, m_config.g200params.color);
capturer->open(m_config,fpgaparam);
imagehandler->Set_ratio(fpgaparam.HRatio, fpgaparam.VRatio);
}
if (m_config.g200params.is_autopaper)
scancount = 65536;
unsigned int reg0;
mb->read(0x00, reg0);
SMBCONFIG *smb_config = (SMBCONFIG *)&reg0;
if((m_cap.papertype == 52 || m_cap.papertype == 54) && (capturer_type > 0))
smb_config->dpi_mode = 2;
else
smb_config->dpi_mode = slow_moire ? 1 : m_config.g200params.dpi -1;
printf(" \n smb_config->dpi_mode =%d ", smb_config->dpi_mode);
mb->write(0x00, reg0);
scannerinfo = getscannerinfo();
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;
#ifdef G100
mb->set_speed_mode(slow_moire ? 2 : (spdmode == 4 ? 3 : spdmode));
if((mbversion.length() >=8)&&(atoi(mbversion.substr(mbversion.length()-6,6).c_str()) >= 230713))
mb->set_speed_mode_v_temp(slow_moire ? 2 :spdmode);
#else
mb->set_speed_mode(spdmode);
if(capturer_type > 0) mb->set_slowmoire(m_config.g200params.dpi == 2?false:slow_moire);
else mb->set_slowmoire(slow_moire);
if((mbversion.length() >=8)&&(atoi(mbversion.substr(mbversion.length()-6,6).c_str()) >= 230713))
mb->set_speed_mode_v_temp(spdmode);
#endif
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);
update_mem_syslog("PC Sent stop msg",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);
update_mem_syslog("Flatting scanner now",true);
}
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,slow_moire);
}
}
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();
#ifdef G200
if((mbversion.length() > 6)&&(atoi(mbversion.substr(2,6).c_str()) > 230801))
{
this_thread::sleep_for(chrono::milliseconds(20));
std::uint32_t reg_2 = 0;
mb->read(2,reg_2);
printf(" mb reg2 value =0x%x \n",reg_2);
if((reg_2&0x200000) == 0)
mb->pick_paper();
}
#endif
{
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);
bool autosize = !(m_config.g200params.is_fixedpaper || (m_config.g200params.paper < (uint)PaperSize::G400_AUTO));
printf(" is_fixedpaper = %d paper = %d \n", m_config.g200params.is_fixedpaper,m_config.g200params.paper);
if(capturer_type > 0){
autosize |= m_cap.papertype == 52 || m_cap.papertype == 54;
scan_process_8478(!autosize);
}
else{
if(autosize) autosizescan();
else fixedsizescan();
}
savescannerinfo(scannerinfo);
printf(" scan processs exit : %s\n",GetCurrentTimeStamp(2).c_str());
while (!imagehandler->done())
this_thread::sleep_for(chrono::milliseconds(10));
done_scan = 0;
if (wake.get())
{
wake->resettime();
wake->setsleepfalg(false);
}
//system("sudo cpufreq-set -g ondemand");
if(capturer_type > 0)
{
capturer->stopsnap();
imagehandler->free_frame_data(autosize ? 1:2);
}
// 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();
mb->set_double_out_en(false);
update_disk_syslog("On scan session done",true);
update_mem_syslog("On scan session done",true);
printf("-------scanner done-------\n");
}
bool Scanner::ExceptionCheck()
{
bool ret = true;
int Contamination_Ret = 0;
unsigned int val;
if(m_cap.en_contaminationdetection)
Contamination_Ret = capturer_type > 0 ? ContaminationDetection_8478(): ContaminationDetection();
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});
mb_error_code = 0x4;
}
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;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
while (top_wh.elapsed_s() < 10)
{
if (is_ml_top || mb_error_code || handstop || (!ret))
break;
this_thread::sleep_for(chrono::milliseconds(1));
}
if ((!is_ml_top || mb_error_code || handstop || Contamination_Ret) && ret)
{
if(ret && (Contamination_Ret > 0) && (mb_error_code == 0))
{
std::this_thread::sleep_for(std::chrono::seconds(1));
mb->stop();
if(Contamination_Ret == 1)
imagehandler->add_scanevent({.From = MtBoard, .Code = 0x100000});
}
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);
imagehandler->add_scanevent({.From = STOPSCAN, 1});
}
this_thread::sleep_for(chrono::milliseconds(20));
imagehandler->add_scanevent({.From = STOPSCAN, 0});
if (wake.get())
{
wake->resettime();
wake->setsleepfalg(false);
}
ret = false;
}
LOG_TRACE(string_format("waiting paper wait_arrival_top time = %0.2f ", top_wh.elapsed_ms()));
#else
if(ret && (Contamination_Ret > 0))
{
mb->stop();
if(Contamination_Ret == 1)
{
ret = false;
imagehandler->add_scanevent({.From = MtBoard, .Code = 0x100000});
}
if (m_config.g200params.is_autopaper){
mb->set_auto_paper(false, false);
imagehandler->add_scanevent({.From = STOPSCAN, 1});
}
}
#endif
uint reg5 =0;
mb->read(5,reg5);
printf("!!!!! motorboard regs 5 : 0x%x \n",reg5);
return ret;
}
int Scanner::ContaminationDetection()
{
int ret = 0;
capturer->snap();
std::this_thread::sleep_for(std::chrono::milliseconds(30));
uint32_t h = capturer->getautosizeheight();
printf("\n-----------ContaminationDetection----------height-----%d-----\n",h);
uint32_t channel = capturer->color() == 16 ? 3 : 1;
uint32_t w = capturer->width()* 2 * 3 * channel;
void *data = nullptr;
if(data = capturer->readFrame(1000))
{
cv::Mat mat = cv::Mat(h, w, CV_8UC1, data);
cv::Mat roi = mat(cv::Rect(0,std::max(mat.rows -10,3),mat.cols,std::min(h-3,10u)));
cv::Mat merge_mat = GetMergeMat(w/channel, roi.rows, channel == 3 ? CV_8UC3 : CV_8UC1, roi,mfpgaversion);
correctColor(merge_mat,m_config.g200params.dpi,merge_mat.channels()==3?1:0,!m_config.g200params.is_textcorrect);
//if(merge_mat.channels() == 3) cv::cvtColor(merge_mat,merge_mat,cv::COLOR_RGB2GRAY);
if(ContaminationDetection::detect2(merge_mat.data,merge_mat.cols,merge_mat.rows,merge_mat.channels(),40,m_config.g200params.dpi == 3 ?4:2)){
ret = 1;
//imagehandler->add_scanevent({.From = MtBoard, .Code = 0x100000});
}
LOG_TRACE(string_format("ContaminationDetection %d \n",ret));
}
else
{
imagehandler->add_scanevent({.From = V4L2, .Code = 0});
done_scan = true;
ret = 2;
LOG_TRACE("capture error");
}
return ret;
}
int Scanner::ContaminationDetection_8478()
{
int ret = 0;
cv::Mat mat = capturer->read_one_frame();
if(mat.empty())
{
imagehandler->add_scanevent({.From = V4L2, .Code = 0});
done_scan = true;
ret = 2;
LOG_TRACE("capture error");
}
else
{
cv::Mat roi = mat(cv::Rect(0,std::max(mat.rows -10,3),mat.cols,std::min(mat.rows-3,10)));
correctColor(roi,m_config.g200params.dpi,roi.channels()==3?1:0,!m_config.g200params.is_textcorrect);
if(ContaminationDetection::detect2(roi.data,roi.cols,roi.rows,roi.channels(),40,m_config.g200params.dpi == 3 ?4:2)){
ret = 1;
}
LOG_TRACE(string_format("ContaminationDetection lvds %d \n",ret));
}
return ret;
}
void Scanner::ControlFeedMode(){
MotorboardParam::MBParam mbparam_tmp = MotorboardParam().GetParam();
if (mbparam_tmp.automaticcontrolfeedmode)
{
printf("\n+++++++++ automaticcontrolfeedmode mb_error_code = %d ",mb_error_code);
MotorSessionInfo::MBTaskRecordInfo info_tmp{0};
if (mb_error_code == 0)
info_tmp.NormalDone = true;
if ((mb_error_code & 0x8) == 0x8)
info_tmp.FeedError = true;
if ((mb_error_code & 0x10) == 0x10)
info_tmp.Jammed = true;
if ((mb_error_code & 0x20) == 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(capturer_type))
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)) || (mb_error_code == 0xffffffff))
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)
{
int tdpi = m_config.g200params.dpi == 0x02 ? 300 : (m_config.g200params.dpi == 0x03 ? 600 : 200);
int min_height = 210*(tdpi)*(slow_moire ? ( m_config.g200params.dpi == 0x02 ? 1.36 : 2.07) :1)*10/254;
int delaytime = m_config.g200params.dpi == 0x02 ? 100 : (m_config.g200params.dpi == 0x03 ? 250 : 30) + slow_moire *100;
this_thread::sleep_for(chrono::milliseconds(delaytime)); //纸张过了 多采集几张
capturer->regs()->read(14,height);
printf("\n------------------min_height--- %d----height------- %d----- ",min_height,height);
StopWatch min_sw;
while ((height < min_height)&&(min_sw.elapsed_ms()<500))
{
std::this_thread::sleep_for(std::chrono::milliseconds(30));
capturer->regs()->read(14,height);
}
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,slow_moire,mb_error_code);
data = NULL;
update_disk_syslog("On snaped " + std::to_string(scancount)+" th paper",true);
update_mem_syslog("On snaped " + std::to_string(scancount)+" th paper",true);
}
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");
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)) || (mb_error_code == 0xffffffff))
break;
else
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
}
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,slow_moire,mb_error_code);
update_disk_syslog("On snaped " + std::to_string(scancount)+" th paper",true);
update_mem_syslog("On snaped " + std::to_string(scancount)+" th paper",true);
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");
update_mem_syslog("Snap error while scannning",false);
}
}
}
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
{
break;
}
}
}
void Scanner::scan_process_8478(bool is_fixed)
{
scannum = 0;
StopWatch sw;
std::future<void> m_read_frame;
std::future<void> m_init_frame;
ThreadPool tp_read_frame(1);
ThreadPool tp_init_frame(1);
frame_data_info frame_info_sanp{0};
if(is_fixed){
frame_info_sanp = imagehandler->init_frame_data_info(capturer->frame_data_size());
}
else
frame_info_sanp = imagehandler->init_frame_data_info(capturer->frame_data_size().area());
for (;;)
{
if (!done_scan) //&& mb->wait_paper_in(10000)
{
if(mb->wait_paper_in(10000))
{
if(mb_error_code != 0)
break;
capturer->snap(frame_info_sanp);
printf("wait_paper_in :%f ms \n",sw.elapsed_ms());
m_init_frame = tp_init_frame.enqueue([is_fixed,&frame_info_sanp,this]
{
if(is_fixed) frame_info_sanp = imagehandler->init_frame_data_info(capturer->frame_data_size());
});
}
else{
printf("paper in exit \n");
done_scan = true; break;
}
printf("waiting paper in :%f ms \n",sw.elapsed_ms());
if (int ret = waitpaperout())
{
printf("\n+++++ waiting paper end :%fms+++++++++++\n", sw.elapsed_ms());
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)) || (mb_error_code == 0xffffffff))
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;
}
{
// if(slow_moire) std::this_thread::sleep_for(std::chrono::milliseconds(50));
if(m_read_frame.valid()) m_read_frame.get();
if(m_init_frame.valid()) m_init_frame.get();
if(!is_fixed){
int delay_time = (m_config.g200params.dpi == 1? 20:(m_config.g200params.dpi == 2? 60: 160)) + ((m_cap.papertype == 52 || m_cap.papertype == 54) ? 200 : 0);
printf("\n+++++ auto size delay : %d ms +++++++++\n", delay_time);
std::this_thread::sleep_for(std::chrono::milliseconds(delay_time));
}
bool delay_pick = ((capturer->multi_frame_counts() - capturer->multi_curr_snap_index()) > (m_config.g200params.color? 7 : 2))
|| (m_cap.is_dogeardetection || m_cap.en_sizecheck) || m_cap.papertype == 52 || m_cap.papertype == 54;
printf("\n+++++ m_read_frame future get :%f ms++ delay_pick : %d +++++++++\n", sw.elapsed_ms(),delay_pick);
if ((!delay_pick) && (!pickpaper()))
done_scan = 1;
m_read_frame = tp_read_frame.enqueue([this,&sw,delay_pick,is_fixed]
{
frame_data_info p_data = capturer->ReadMultiFrame(!is_fixed);
if (p_data.offset)
{
size_t width_mat = capturer->width()*(m_config.g200params.color == 1 ? 3:1)*2;
printf("\n+++++ readFrame:%fms+++++++++++ \n %s \n", sw.elapsed_ms(),p_data.to_str().c_str());
if (imagehandler)
{
imagehandler->add_image(p_data.pdata, width_mat, p_data.img_h, capturer->color(), scannum,is_fixed ? 2 : 1,capturer_type,mfpgaversion,slow_moire,mb_error_code);
}
printf("\n+++++ addimage:%fms+++++++++++\n", sw.elapsed_ms());
if (imagehandler->getimgstatus().status != NO_error)
{
printf("\n+++++ status :%d ms+++++++++++\n", imagehandler->getimgstatus().status);
mb->stop();
done_scan = 1;
mb->PutMsg( imagehandler->getimgstatus().status == Error_Status::Dog_error?DisType::Dis_Err_DogEar: DisType::Dis_Err_Size, 0, ClearScreen::All);
}
if (delay_pick && (!pickpaper()))
done_scan = 1;
scannerinfo.RollerNum++;
scannerinfo.TotalScanned++;
}
else
{
imagehandler->add_scanevent({.From = V4L2, .Code = 0});
done_scan = true;
LOG_TRACE("capture error");
printf("capture error \n");
}
});
if(delay_pick)
if(m_read_frame.valid())
m_read_frame.get();
}
}
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
{
break;
}
}
}
void Scanner::clean_paper_road()
{
if(mb.get())
mb->clean_paper_road();
}
int Scanner::waitpaperout()
{
//if (mb->wait_paper_out(m_config.g200params.dpi == 3 ? 10000 :(m_config.g200params.dpi == 2 ? 7000 : 4000))) //10秒内收到正常翻转信号或者异常时 返回 1 继续扫描
int timeout_ms = 10000;
if((capturer_type > 0) && (m_cap.papertype == 52 || m_cap.papertype == 54))
timeout_ms = (m_cap.maxszie_sanp_height+17)/18*1000;
printf(" wait paper out timeout_ms = %d \n",timeout_ms);
if(mb->wait_paper_out(timeout_ms))
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;
}
void Scanner::single_correct(std::uint32_t mode){
capturer->single_correct(mode);
HGIntInfo info = {.From = AutoCorrect, .Code = 4, .Img_Index =0};
if (imagehandler.get())
imagehandler->add_scanevent(info);
}
void Scanner::set_sensor_param(int type, uint32_t val)
{
if(!mb.get())
return;
auto p = Get_Static_SC().get_mem_param();
std::vector<uint32_t> params(sizeof(SensorConfig::SensorConfig_Param)/sizeof(uint32_t));
memcpy(&params[0],&p,sizeof(SensorConfig::SensorConfig_Param));
if(((type >= 0) || (type < 6)) && (val < 100))
{
params[type] = val;
mb->set_sensor_pwm_duty(type+1,val);
}
if((type >= 6) || (type < 10))
{
params[type] = val;
mb->set_ultrasonic_param(type-5,val);
}
if((type == 10) || (type == 11))
{
params[type] = (bool)val;
}
memcpy(&p,&params[0],sizeof(SensorConfig::SensorConfig_Param));
Get_Static_SC().set_param(p);
}
std::uint32_t Scanner::get_ultrasonic_version()
{
if(!mb.get()) return 0;
return mb->get_ultrasonic_version();
}
void Scanner::update_disk_syslog(std::string info,bool bprintf_diskinfo)
{
if(bprintf_diskinfo)
{
_fileSystem_info fileinfo;
u_get_fileSystem_info("/",&fileinfo);
std::string diskinfo = "Disk contains "+std::to_string(fileinfo.fileSystem_total_capacity)+"KB Total,"+ std::to_string(fileinfo.fileSystem_free_capacity)+"KB free now."+info;
writesyslog(6,diskinfo);
}
else
{
//记录常规信息时使用update_mem_syslog 接口
}
}
void Scanner::update_mem_syslog(std::string info,bool bprinf_meminfo)
{
if(bprinf_meminfo)
{
std::string info2log = u_getmeminfo();
writesyslog(6,info2log+info);
}
else
writesyslog(6,info);
}