twain3.0/huagao/Device/GScanO400.cpp

657 lines
16 KiB
C++
Raw Normal View History

#include "stdafx.h"
#include "GScanO400.h"
#include "UsbScanEx.h"
#include "StopWatch.h"
#include "scn_config.h"
#include "ImageMatQueue.h"
#include "ImageProcess/ImageApplyDogEarDetection.h"
#include "filetools.h"
#include "GetMemoryUsage.h"
#include "G400ScanConfig.h"
//u32_CMD
typedef enum tagUsbKeyWords : UINT32
{
//无命令
NO_COMMAND = 0,
//获取dsp 状态
GET_DSP_STATUS = 1,
//取图
GET_IMAGE = 2,
//销毁DSP中驻存的图
POP_IMAGE = 3,
//开始扫描命令
START_COMMAND = 4,
//停止扫描命令
STOP = 5,
//获取扫描仪扫描模式
GET_SCAN_MODE = 6,
//获取固件版本号
GET_FW_VERSION = 7,
//返回PC端的状态
SEND_STATUS_PC = 8,
//下发扫描配置参数
CONFIGURED_DATA = 9,
//下发固件信息
SEND_FW = 10,
//获取扫描参数
GET_CONFIG_DATA = 11,
//获取扫描总张数
GET_SCANN_NUM = 12,
//获取有无纸的状态
GET_PAPERFEEDER_STATUS = 13,
//DSP初始化
INIT_HARDWARE_SYS = 14,
//获取有无纸的状态
GET_PAPER_STATUS = 0x0d,
//下发元器件配置参数灰度LED R曝光时间
SEND_COMPONENTS_GR = 15,
//下发元器件配置参数LED G/B曝光时间
SEND_COMPONENTS_GB = 16,
//下发扫描模式
SEND_SCAN_MODE = 17,
//开始进行平场矫正
START_FLAT = 18,
//停止平场矫正
STOP_FLAT = 19,
//下发200dpi彩色平场矫正参数
SEND_200_COLOR_FLAT_DATA = 20,
//下发300dpi彩色平场矫正参数
SEND_300_COLOR_FLAT_DATA = 21,
//获取200dpi彩色平场矫正参数
GET_200_COLOR_FLAT_DATA = 22,
//获取300dpi彩色平场矫正参数
GET_300_COLOR_FLAT_DATA = 23,
//下发200dpi灰度平场校正参数
SEND_200_GRAY_FLAT_DATA = 24,
//下发300dpi灰度平场校正参数
SEND_300_GRAY_FLAT_DATA = 25,
//获取200DPI灰度平场校正参数
GET_200_GRAY_FLAT_DATA = 26,
//获取300DPI灰度平场校正参数
GET_300_GRAY_FLAT_DATA = 27,
//下发序列号命令
SEND_SERIAL = 28,
//获取序列号命令
GET_SERIAL = 29,
//获取滚轴数
GET_ROLLER_NUM = 0x1e,
//清零滚轴数
CLR_ROLLER_NUM = 0x1f,
//清除扫描总张数
CLR_SCAN_NUM = 0x20,
//准备更新固件
PRE_UPGRADE = 0X21,
//开始更新固件
START_UPGRADE = 0x22,
//彩色的AD参数
RGB_ADI_PARA = 0x23,
//灰度的AD参数
ADI_PARA = 0x24,
//获取CIS参数曝光时间ad参数)
GET_CIS_PARA = 0x25,
//扫描张数
START_COMMAND_COUNT = 0x26,
//下发休眠时间
SET_SLEEP_TIME = 0x27,
//获取休眠时间
GET_SLEEP_TIME = 0x28,
//清除缓存
CLR_CACHE = 0x29,
//下发速度模式
SET_SPEED_MODE = 0x2a,
//获取扫描速度模式
GET_SPEED_MODE = 0X2b,
//设置固件版本一共8个字节
SET_FW_VERSION = 0X2c,
//获取DSP版本
GET_DSP_VERSION = 0X2d,
//采集板FPGA固件版本
GET_SCANFPGA_VERSION = 0x2e,
//电机板FPGA固件版本
GET_MOTORFPGA_VERSION = 0X2f,
//设置制造商信息
SET_USB_INFOR_MANUFACTURE = 0X30,
//获取制造商信息
GET_USB_INFOR_MANUFACTURE = 0X31,
//设置产品型号信息
SET_USB_INFOR_MODEL_NAME = 0X32,
//获取产品型号信息
GET_USB_INFOR_MODEL_NAME = 0X33,
//设置USB PID / VID信息
SET_USB_INFOR_VIDPID = 0X34,
GET_USB_INFOR_VIDPID = 0X35,
//设置卡纸急停检测灵敏度
SET_JAM_DETECT_SENSITIVE = 0X36,
//获取卡纸急停检测灵敏度
GET_JAM_DETECT_SENSITIVE = 0X37,
//设置横向畸变系数
SET_JUST_COF_H = 0x38,
//读取横向畸变系数
GET_JUST_COF_H = 0x39,
CLEAR_HWERROR = 0x40,//G400 清除硬件异常
//设置纵向畸变系数
SET_JUST_COF_V = 0x41,
//读取纵向畸变系数
GET_JUST_COF_V
} UsbKeyWords, * PUsbKeyWords;
GScanO400::GScanO400() :
huagods(NULL),
image_num(0),
m_bread_fixed_ratio_fromDSP(false)
{
m_pImages.reset(new ImageMatQueue());
m_pImages->Getimagenumber = std::bind(&GScanO400::Getimagenumber,this, std::placeholders::_1);
}
GScanO400::~GScanO400()
{
if (m_threadUsb && m_threadUsb->joinable()) {
devState = DEV_STOP;
m_threadUsb->join();
m_threadUsb.reset();
}
if (m_usb.get())
m_usb.reset();
}
void GScanO400::Getimagenumber(bool isadd)
{
if (isadd)
{
image_num++;
}
else
{
image_num--;
}
}
void GScanO400::DogEar_callback(std::function<void(int)> fun)
{
m_pImages->DogEarDetection_callback = fun;
}
void GScanO400::open(int vid, int pid)
{
auto usbs = UsbScan_List::find_vid_pid(vid, pid);
if (!usbs.empty())
{
m_usb = *usbs.begin();
bool ret = m_usb->open();
USBCB status = { GET_DSP_STATUS ,0,0 };
if (m_usb.get() && m_usb->is_connected())
m_usb->write_bulk(&status, sizeof(status));
if (m_usb.get() && m_usb->is_connected())
m_usb->read_bulk(&status, sizeof(status));
if (ret) {
m_usb->set_usbhotplug_callback(usbhotplug_callback, this);
}
}
}
void GScanO400::regist_deviceevent_callback(deviceevent_callback callback, void* usrdata)
{
huagods = usrdata;
dev_callback = callback;
}
#ifdef LOG_NORMAL
fstream fsaquire;
static int aquiretimes = 1;
#endif // LOG
int GScanO400::aquire_bmpdata(std::vector<unsigned char>& bmpdata)
{
StopWatch sw;
while (true)
{
if (m_pImages->empty()) {
DoEvents();
this_thread::sleep_for(chrono::milliseconds(1));
if (sw.elapsed_s() > 20.00)
{
if (m_threadUsb && m_threadUsb->joinable()) {
devState = DEV_STOP;
m_threadUsb->join();
m_threadUsb.reset();
//writelog("aquire_bmpdata m_threadUsb.reset();");
}
Stop_scan();//停止扫描
ResetScanner();
return HARDWARE_ERROR;
}
if (!is_scan()) {
if (devState == DEV_WRONG) {
return get_ErrorCode();
}
return -1;
}
}
else {
if (m_pImages->valid()) {
bmpdata = *(m_pImages->popBmpdata());
//static int aqimgindex = 0;
//writelog("aquireed image " + to_string(++aqimgindex));
//FileTools::write_log("C:\\Users\\huagao\\Desktop\\out.txt", "aquired procced image "+ to_string(++aqimgindex));
#ifdef LOG_NORMAL
static int aquireindex = 0;
FileTools::write_log("out.txt", "aquire image index " + std::to_string(++aquireindex));
#endif // LOG
return 0;
}
DoEvents();
this_thread::sleep_for(chrono::milliseconds(2));
}
}
}
BOOL GScanO400::IsConnected()
{
return m_usb.get() && m_usb->is_connected();
}
std::string GScanO400::GetFWVersion()
{
if (m_usb.get() && m_usb->is_connected()) {
lock_guard< mutex> lock(m_imgLocker);
if (fwVersion.empty()) {
fwVersion.resize(10);
USBCB cmd = { GET_FW_VERSION,fwVersion.size(),0, };
m_usb->write_bulk(&cmd, sizeof(cmd));
m_usb->read_bulk(&fwVersion[0], fwVersion.size());
}
return fwVersion;
}
return "";
}
std::string GScanO400::GetSerialNum()
{
//return "G20018000298";
if (m_usb.get() && m_usb->is_connected())
{
std::lock_guard<std::mutex> lck(m_imgLocker);
if (SerialNum.empty()) {
SerialNum.resize(14);
USBCB usbcb = { GET_SERIAL,SerialNum.size(),0 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
m_usb->read_bulk(&SerialNum[0], SerialNum.size());
}
return SerialNum;
}
return "";
}
bool GScanO400::is_scan()
{
//std::lock_guard<std::mutex> lck(m_imgLocker);
return devState == DEV_ISRUNNING;
}
BOOL GScanO400::Get_Scanner_PaperOn()
{
if (m_usb.get() && !m_usb->is_open())
return false;
USBCB usbcb = { GET_PAPER_STATUS ,0,0 };
usbcb.u32_Data = 1;
std::lock_guard<std::mutex> lck(m_imgLocker);
m_usb->write_bulk(&usbcb, sizeof(usbcb));
if (0 == m_usb->read_bulk(&usbcb, sizeof(usbcb)))
{
Set_ErrorCode(USB_DISCONNECTED);
return true;
}
return usbcb.u32_Data != 0;
}
void GScanO400::config_params(GScanCap& params)
{
if (m_usb.get() && m_usb->is_connected()) {
G400ScanConfig cfg = G400ScanConfig(params);
gcap = params;
UINT32 cfgdata = cfg.GetData();
USBCB usbcb = { CONFIGURED_DATA,cfgdata,0 };
FileTools::write_log("USB config_params:"+to_string(cfgdata)+"\npaper:"+to_string(cfgdata&0x1f)
+ "\ncolor:" + to_string((cfgdata>>5) & 0x1)
+ "\ndpi:" + to_string((cfgdata>>6) & 0x3)
+ "\ndouble_feed_enbale:" + to_string((cfgdata>>8) & 0x1)
+ "\nstable_enbale:" + to_string((cfgdata>>9) & 0x1)
+ "\nscrew_detect_enable:" + to_string((cfgdata>>10) & 0x1)
+ "\nscrew_detect_level:" + to_string((cfgdata>>11) & 0x7)
+ "\nunused_one:" + to_string((cfgdata>>14) & 0x3F)
+ "\npc_correct:" + to_string((cfgdata>>20) & 0x1)
+ "\nunused_two:" + to_string((cfgdata>>21) & 0x7ff));
m_usb->write_bulk(&usbcb, sizeof(USBCB));
this_thread::sleep_for(std::chrono::milliseconds(200));
m_pImages->setparam(params);
}
}
void GScanO400::Scanner_StartScan(UINT16 count)
{
std::lock_guard<std::mutex> lck(m_imgLocker);
if (m_threadUsb && m_threadUsb->joinable()) {
devState = DEV_STOP;
m_threadUsb->join();
}
USBCB status = { GET_DSP_STATUS ,0,0 };
if (m_usb.get() && m_usb->is_connected())
m_usb->write_bulk(&status, sizeof(status));
if (m_usb.get() && m_usb->is_connected())
m_usb->read_bulk(&status, sizeof(status));
switch (status.u32_Data)
{
case COUNT_MODE:
case NO_FEED:
case OPEN_COVER:
case FEED_IN_ERROR:
case PAPER_JAM:
case DETECT_DOUBLE_FEED:
case DETECT_STAPLE:
case PAPER_SKEW:
case HARDWARE_ERROR:
case PC_SCAN_BUSY_or_ERROR:
m_pImages->setscanflags(false);
devState = DEV_WRONG;
Set_ErrorCode(status.u32_Data);
if (huagods)
dev_callback(status.u32_Data, huagods);
return;
default:
break;
}
int readlenght = 0;
USBCB paperstatus = { GET_PAPER_STATUS ,0,0 };
if (m_usb.get() && m_usb->is_connected())
m_usb->write_bulk(&paperstatus, sizeof(paperstatus));
if (m_usb.get() && m_usb->is_connected())
readlenght= m_usb->read_bulk(&paperstatus, sizeof(paperstatus));
if (paperstatus.u32_Data == 0) {
m_pImages->setscanflags(false);
devState = DEV_WRONG;
int errorcode = 0;
readlenght == 0 ? errorcode = USB_DISCONNECTED : errorcode = NO_FEED;
Set_ErrorCode(errorcode);
if (huagods)
dev_callback(errorcode, huagods);
return;
}
m_pImages->reset_DogEar();
if (gcap.is_duplex)
count = count == 65535 ? 65535 : count / 2;
USBCB usbcb = { START_COMMAND,(UINT32)count ,0 };
if (m_usb.get() && m_usb->is_connected())
m_usb->write_bulk(&usbcb, sizeof(usbcb));
this_thread::sleep_for(std::chrono::milliseconds(200));
if (m_usb.get() && m_usb->is_connected())
{
m_pImages->setscanflags(true);
m_threadUsb.reset(new std::thread(&GScanO400::usbmain, this));
m_pImages->run();
}
}
void GScanO400::Stop_scan()
{
std::lock_guard<std::mutex> lck(m_imgLocker);
USBCB usbcb = { STOP ,0,0 };
if (m_usb.get() && m_usb->is_connected())
m_usb->write_bulk(&usbcb, sizeof(usbcb));
}
void GScanO400::ResetScanner()
{
if (m_usb.get() && !m_usb->is_connected())
return;
std::lock_guard<std::mutex> lck(m_imgLocker);
USBCB usbcb = { INIT_HARDWARE_SYS ,0,0 };
if (m_usb.get() && m_usb->is_connected())
m_usb->write_bulk(&usbcb, sizeof(usbcb));
}
bool GScanO400::Get_IsImageQueueEmpty()
{
return m_pImages->empty();
}
void GScanO400::reset()
{
while (!m_pImages->empty())
m_pImages->clear();
}
void GScanO400::setdecodepixtype(int twpixtype)
{
}
UINT32 GScanO400::get_ErrorCode()
{
return Error_Code;
}
void GScanO400::Set_ErrorCode(UINT32 value)
{
Error_Code = value;
}
int GScanO400::get_scanned_num()
{
std::lock_guard<std::mutex> lck(m_imgLocker);
USBCB usbcb = { GET_SCANN_NUM ,0,0 };
if (m_usb.get() && m_usb->is_connected())
m_usb->write_bulk(&usbcb, sizeof(usbcb));
return usbcb.u32_Count;
}
void GScanO400::clear_hwerror()
{
std::lock_guard<std::mutex> lck(m_imgLocker);
USBCB usbcb = { CLEAR_HWERROR ,0,0 };
if (m_usb.get() && m_usb->is_connected())
m_usb->write_bulk(&usbcb, sizeof(usbcb));
}
void GScanO400::usbhotplug_callback(bool isconnect, void* userdata)
{
GScanO400* This = (GScanO400*)userdata;
This->usbhotplug(isconnect);
}
void GScanO400::usbhotplug(bool isleft)
{
if (isleft) {
devState = DEV_WRONG;
Error_Code = USB_DISCONNECTED;
m_pImages->setscanflags(false);
if (m_usb.get())
m_usb.reset();
if (huagods)
dev_callback(USB_DISCONNECTED, huagods);
}
}
void GScanO400::updateHVRatio()
{
if (m_usb.get() && !m_usb->is_connected())
return;
if (m_bread_fixed_ratio_fromDSP) {
USBCB usbcb = { GET_JUST_COF_H ,0,0 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
m_usb->read_bulk(&usbcb, sizeof(usbcb));
float hratio = *((float*)(&usbcb.u32_Data));
usbcb = { GET_JUST_COF_V ,0,0 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
m_usb->read_bulk(&usbcb, sizeof(usbcb));
float vratio = *((float*)(&usbcb.u32_Data));
m_pImages->updatefixratio(hratio, vratio);
}
}
void GScanO400::usbmain()
{
std::shared_ptr<std::vector<char>> imgData;
devState = DEV_ISRUNNING;
bool haveError = false;
try
{
StopWatch sw;
while (devState == DEV_ISRUNNING) {
if ((m_usb.get() && !m_usb->is_connected())) {
this_thread::sleep_for(chrono::milliseconds(200));
break;
}
if (sw.elapsed_ms() > 10000)
{
m_pImages->setscanflags(false);
devState = haveError ? DevState::DEV_WRONG : DevState::DEV_STOP;
return;
}
if(gcap.resolution_dst>200.0f)
{
if (m_pImages->orginimgcount() > 2)
{
this_thread::sleep_for(chrono::milliseconds(10));
continue;
}
}
USBCB usbcb = Get_Scanner_Status();
switch (usbcb.u32_Data) {
case HAVE_IMAGE:
{
int totalNum = usbcb.u32_Count;
m_usb->set_timeout(2000);
imgData = Get_Img_Data(totalNum);
if (!imgData->size()) {
Stop_scan();
writelog("imgData->size() error");
break;
}
if(!m_pImages->get_isDogEar())
m_pImages->pushMat(std::shared_ptr<IDecode>(new G400Decode(imgData)));
m_usb->set_timeout(200);
Pop_Image();
sw.reset();
break;
}
case STOP_SCAN:
m_pImages->setscanflags(false);
devState = haveError ? DevState::DEV_WRONG : DevState::DEV_STOP;
//m_pImages->setscanflags(false);
//devState = DEV_STOP;
break;
case COUNT_MODE:
case NO_FEED:
case OPEN_COVER:
case FEED_IN_ERROR:
case PAPER_JAM:
case DETECT_DOUBLE_FEED:
case DETECT_STAPLE:
case PAPER_SKEW:
case HARDWARE_ERROR:
case PC_SCAN_BUSY_or_ERROR:
case SIZE_ERROR:
if (!haveError)
{
haveError = true;
Set_ErrorCode(usbcb.u32_Data);
if (huagods)
dev_callback(usbcb.u32_Data, huagods);
}
break;
case NORMAL:
break;
default:
break;
}
this_thread::sleep_for(chrono::milliseconds(10));
}
}
catch (const std::exception& e)
{
writelog(e.what());
}
////FileTools::write_log("D:\\1.txt", "thread usb exit");
}
///////////////////////////////////////////////////////////////////////////
USBCB GScanO400::Get_Scanner_Status()
{
if (m_usb.get() && !m_usb->is_connected()) {
return { NO_COMMAND ,PC_SCAN_BUSY_or_ERROR ,0 };
}
USBCB usbcb = { GET_DSP_STATUS ,0,0 };
if (m_usb.get() && m_usb->is_connected())
m_usb->write_bulk(&usbcb, sizeof(usbcb));
if (m_usb.get() && m_usb->is_connected())
m_usb->read_bulk(&usbcb, sizeof(usbcb));
return usbcb;
}
std::shared_ptr<std::vector<char>> GScanO400::Get_Img_Data(int bufferSize)
{
if (m_usb.get() && !m_usb->is_connected())
return std::shared_ptr<std::vector<char>>(new std::vector<char>());
std::shared_ptr<std::vector<char>> imData(new std::vector<char>(bufferSize));
StopWatch sw;
int readed = 0;
USBCB usbcb = { GET_IMAGE,0,bufferSize };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
int totalength = bufferSize;
int startindex = 0;
while (totalength > 0)
{
int dstlength = 1024 * 1024;
if (totalength <= dstlength)
{
dstlength = totalength;
totalength = 0;
}
else
totalength -= dstlength;
int tt = m_usb->read_bulk(imData->data() + startindex, dstlength);
startindex += dstlength;
}
if (sw.elapsed_ms() > 5000)
{
writelog("Usb read data timeout\n");
}
return imData;
}
///////////////////////////////////////////////////////////////////////////
void GScanO400::Pop_Image()
{
if (m_usb.get() && !m_usb->is_open())
return;
USBCB usbcb = { POP_IMAGE ,0,0 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
}