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

503 lines
12 KiB
C++
Raw Normal View History

2023-04-08 00:56:20 +00:00
#include "scanner.h"
#include <iostream>
#include "Imotorboard.h"
2023-04-08 00:56:20 +00:00
#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 "Gpio.h"
#include "correct_ultis.h"
2023-04-08 00:56:20 +00:00
static const std::string loggername = "Scanner";
Scanner::Scanner(std::shared_ptr<ICapturer> capturer, std::shared_ptr<IMotorBoard> mb, std::shared_ptr<WakeUp> wake):IScanner(capturer,mb,wake)
2023-04-08 00:56:20 +00:00
{
LOG_INIT();
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;
LOG_TRACE("callback FEED IN ERROR\n");
}
else if (error_code & 0x10)
{
code = 0x10;
LOG_TRACE("callback PAPER JAM\n");
}
else if (error_code & 0x20)
{
code = 0x20;
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 ---------------\n", code);
if (code != 0)
{
HGIntInfo errType = {.From = MtBoard, .Code = code};
imagehandler->add_scanevent(errType);
done_scan = 1;
}
mb_error_code = code;
if (code != 0)
done_scan = 1;
};
auto mb_scandone_call = [&]()
{
done_scan = 1;
printf("motorboard callback scan_done");
};
auto mb_osmode_call = [&](unsigned int osmode)
{
done_scan = 1;
printf("motorboard callback mb_osmode_call changed");
};
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; //升降台到位
2023-04-08 00:56:20 +00:00
};
auto mb_auto_paper = [&](unsigned int value)
{
printf("连续扫描模式检测到有纸");
if (is_runscan())
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->set_callbacks(mb_glue);
mb->set_auto_paper(m_config.g200params.is_autopaper); //防止程序异常死掉后未关闭连续扫描导致升降台抬升扫描
2023-04-08 00:56:20 +00:00
u32 value;
mb->read(0x00, value);
printf("mb reg[0] = %d \n", value);
2023-04-08 00:56:20 +00:00
value = 0;
mb->read(0x03, value);
if (value >= 35211210)
m_mbver = MotorVersion::Motor_paperout;
else if(value >= 35211126)
m_mbver = MotorVersion::Motor_mltop;
else
m_mbver = MotorVersion::Motor_old;
mbversion = std::to_string(value);
printf("mb reg[0] = %d \n", value);
2023-04-08 00:56:20 +00:00
}
Scanner::~Scanner()
{
}
void Scanner::start_scan()
{
printf("\n ------------------start_scan------------------ \n");
if (is_runscan())
return;
if (wake.get())
wake->setsleepfalg(true);
mb_error_code = is_ml_top = handstop = false;
FPGAConfigParam fpgaparam = GetFpgaparam(m_config.g200params.dpi, m_config.g200params.color);
capturer->open(m_config,fpgaparam);
2023-04-08 00:56:20 +00:00
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;
}
mb->set_speed_mode(spdmode,1,1);
2023-04-08 00:56:20 +00:00
printf("\n set speedmode %d read speedmode %d", spdmode, mb->get_speed_mode());
imagehandler->resetimgstatus();
mb->clear_error();
fu_runscan.reset(new ThreadEx(&Scanner::runScan, this));
}
void Scanner::stop_scan()
{
mb->stop();
handstop = true;
if (m_config.g200params.is_autopaper == 1)
mb->set_auto_paper(false);
}
int Scanner::count()
{
return mb->paper_counter();
}
int Scanner::mode()
{
return mb->os_mode();
}
int Scanner::getmbstatus()
{
mb->clear_error();
uint val = 0;
mb->read(0x01, val);
printf("\n scan stop code =%d ", val & 0x700fe);
return val & 0x700fe;
}
static int pickpapernum = 0;
void Scanner::runScan()
{
pickpapernum = 0;
// system("sudo cpufreq-set -g performance");
system("echo performance > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor");
LOG_TRACE("+++++++scanner runinng+++++++++++++\n");
mb->clear_error();
unsigned int val;
mb->set_double_inpect(m_config.g200params.double_feed_enbale);
mb->set_staple_inpect(m_config.g200params.stable_enbale);
// mb->set_paper_inspect(m_config.g200params.enable_sizecheck);
mb->set_auto_paper(m_config.g200params.is_autopaper);//m_config.g200params.is_autopaper
mb->set_screw_inpect(m_config.g200params.screw_detect_enable);
mb->set_screw_level(m_config.g200params.screw_detect_level);
mb->set_long_paper(m_config.g200params.paper);
//mb->set_cuospeed(41);
mb->start();
mb->read(0x01, val);
if ((val & 0x700fe) > 0)
{
if ((val & 0x700fe) == 0x14)
{
imagehandler->add_scanevent({.From = MtBoard, .Code = 4});
LOG_TRACE("\nCover Open status");
imagehandler->add_scanevent({.From = STOPSCAN, 0});
if (mb_error_code != 0 && m_config.g200params.is_autopaper)
mb->set_auto_paper(false);
return;
2023-04-08 00:56:20 +00:00
}
imagehandler->add_scanevent({.From = MtBoard, .Code = val & 0x700fe});
printf("\n scan stop code =%d ", val & 0x700fe);
}
else
{
#ifdef G200
if ((int)m_mbver > 0)
{
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)
{
if (mb_error_code == 0 && handstop == 0) // 无其他异常时,发送升降台未到达指定位置异常
2023-04-08 00:56:20 +00:00
imagehandler->add_scanevent({.From = MtBoard, 0x80000});
capturer->reset();
this_thread::sleep_for(chrono::milliseconds(20));
imagehandler->add_scanevent({.From = STOPSCAN, 0});
return;
}
}
else
this_thread::sleep_for(chrono::milliseconds(2500));
#endif
done_scan = 0;
if((int)m_mbver > 1)
scanpaperout();
else
scanold();
}
this_thread::sleep_for(chrono::milliseconds(1000));
if (wake.get())
{
wake->resettime();
wake->setsleepfalg(false);
}
imagehandler->add_scanevent({.From = STOPSCAN, 0});
capturer->reset();
if (mb_error_code != 0 && m_config.g200params.is_autopaper)
2023-04-08 00:56:20 +00:00
mb->set_auto_paper(false);
printf("\n-------scanner done-------\n");
}
bool Scanner::getpaperon()
{
#ifdef G200
2023-04-08 00:56:20 +00:00
if (mb.get())
{
uint val = 0;
mb->read(2, val);
return val & 0x10000;
}
return 0;
#endif
return 1;
2023-04-08 00:56:20 +00:00
}
void Scanner::scanpaperout()
{
StopWatch sw;
StopWatch swCap;
void *data = NULL;
int scannum = 0;
startcapimage();
printf("first page pick paper \n");
for (;;)
{
LOG_TRACE("waiting paper");
if (!done_scan) //
{
//LOG_TRACE(string_format("+++++paper on:%fms+++++++++++ ", swCap.elapsed_ms()));
if (mb->wait_paper_out(3000))
{
printf("wait_paper_out time =%f \n",sw.elapsed_ms());
2023-04-08 00:56:20 +00:00
sw.reset();
swCap.reset();
if (data = capturer->readFrame(2000))
{
printf("\n readFrame time =%f pickpapernum = %d",swCap.elapsed_ms(),pickpapernum++);
if (imagehandler)
{
imagehandler->add_image(data, capturer->width(), capturer->height() / 3 * 3, capturer->color(), scannum++,0x90001,CISVendor::DUNNAN_CIS_V0);
2023-04-08 00:56:20 +00:00
data = NULL;
}
swCap.reset();
scannerinfo.RollerNum++;
LOG_TRACE(string_format("capture one=%fms", swCap.elapsed_ms()));
}
else
{
imagehandler->add_scanevent({.From = V4L2, .Code = 0});
// LOG_TRACE("capture error");
// done_scan = 1;
// capturer->stop();
// mb->stop();
LOG_TRACE("capture error Stop Scan");
break;
}
}
else
{
if (!done_scan)
{
uint value = 0;
mb->read(0x2, value);
if (!(value & 0x20000))//bit 17 scandone
{
done_scan = 1;
LOG_TRACE("---------Time out-----");
}
}
}
}
else
{
break;
}
if (imagehandler->getimgstatus().status != NO_error)
{
mb->stop();
done_scan = 1;
capturer->stop();
LOG_TRACE("imagehandler->getimgstatus().dogear_error ");
break;
}
if ((scancount <= scannum))
{
done_scan = 1;
capturer->stop();
this_thread::sleep_for(chrono::milliseconds(2000));
mb->stop();
break;
}
if (m_cap.resolution_dst >= 400 && papersMap[(PaperSize)m_config.g200params.paper].height <= 8100)
this_thread::sleep_for(chrono::milliseconds(3000));
else if (m_cap.resolution_dst >= 400 && (papersMap[(PaperSize)m_config.g200params.paper].height > 8100 && papersMap[(PaperSize)m_config.g200params.paper].height <= 10800))
this_thread::sleep_for(chrono::milliseconds(5000));
else if (m_cap.resolution_dst >= 400 && papersMap[(PaperSize)m_config.g200params.paper].height > 10800)
this_thread::sleep_for(chrono::milliseconds(8000));
startcapimage();
mb->pick_paper();
printf(" pick_paper time =%f \n", swCap.elapsed_ms());
LOG_TRACE("pick_paper");
}
savescannerinfo(scannerinfo);
while (!imagehandler->done())
this_thread::sleep_for(chrono::milliseconds(10));
capturer->close();
done_scan = 0;
system("sudo cpufreq-set -g ondemand");
// system("sudo echo ondemand > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor");
LOG_TRACE("-------scanner done-------\n");
}
void Scanner::scanold()
{
StopWatch sw;
StopWatch swCap;
void *data = NULL;
int scannum = 0;
for (;;)
{
LOG_TRACE("waiting paper");
sw.reset();
if (!done_scan && mb->wait_paper_in(1000))
{
printf("wait_paper_in time =%f \n",swCap.elapsed_ms());
//testGpio->setValue(Gpio::High);
LOG_TRACE(string_format("+++++paper on:%fms+++++++++++ ", swCap.elapsed_ms()));
capturer->snap();
//testGpio->setValue(Gpio::Low);
swCap.reset();
if (data = capturer->readFrame(2000))
{
printf("readFrame time =%f \n",swCap.elapsed_ms());
swCap.reset();
if (imagehandler)
{
imagehandler->add_image(data, capturer->width(), capturer->height() / 3 * 3, capturer->color(), scannum++,0x90001,CISVendor::DUNNAN_CIS_V0);
2023-04-08 00:56:20 +00:00
data = NULL;
}
LOG_TRACE(string_format("readFrame time =%f ",swCap.elapsed_ms()));
printf("addimage time =%f \n",swCap.elapsed_ms());
swCap.reset();
scannerinfo.RollerNum++;
scannerinfo.TotalScanned++;
}
else
{
imagehandler->add_scanevent({.From = V4L2, .Code = 0});
LOG_TRACE("capture error");
}
swCap.reset();
}
else if (done_scan)
{
break;
}
else
{
if (!done_scan)
{
uint value = 0;
mb->read(0x2, value);
if (!(value & 0x20000))//bit 17 scandone
{
printf("\n mb 02 reg value =%d ",value);
done_scan = 1;
LOG_TRACE("---------Time out-----");
break;
}
}
}
if (imagehandler->getimgstatus().status != NO_error)
{
mb->stop();
done_scan = 1;
capturer->stop();
LOG_TRACE("imagehandler->getimgstatus().dogear_error ");
break;
}
if ((scancount <= scannum))
{
done_scan = 1;
capturer->stop();
this_thread::sleep_for(chrono::milliseconds(2000));
mb->stop();
break;
}
if(m_cap.resolution_dst>=400 && papersMap[(PaperSize)m_config.g200params.paper].height<=8100)
this_thread::sleep_for(chrono::milliseconds(3000));
else if(m_cap.resolution_dst>=400 && (papersMap[(PaperSize)m_config.g200params.paper].height>8100&&papersMap[(PaperSize)m_config.g200params.paper].height<=10800))
this_thread::sleep_for(chrono::milliseconds(5000));
else if(m_cap.resolution_dst>=400 && papersMap[(PaperSize)m_config.g200params.paper].height>10800)
this_thread::sleep_for(chrono::milliseconds(8000));
mb->pick_paper();
swCap.reset();
LOG_TRACE("pick_paper");
}
savescannerinfo(scannerinfo);
while(!imagehandler->done())
this_thread::sleep_for(chrono::milliseconds(10));
capturer->close();
done_scan = 0;
system("sudo cpufreq-set -g ondemand");
//system("sudo echo ondemand > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor");
}