twain3.0/huagao/Device/GScanO200.cpp

690 lines
16 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

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

#include "stdafx.h"
#include "GScanO200.h"
#include "UsbScanEx.h"
#include "UsbScanEx.h"
#include "StopWatch.h"
#include "scn_config.h"
#include "JpegBuffer.h"
#include "ImageMatQueue.h"
#include "filetools.h"
#include "GetMemoryUsage.h"
#ifndef G200
#include "G400ScanConfig.h"
#endif // !G200
//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,
#ifndef G200
CLEAR_HWERROR = 0x40,//G400 清除硬件异常
#endif // !G200
//设置纵向畸变系数
SET_JUST_COF_V = 0x41,
//读取纵向畸变系数
GET_JUST_COF_V
} UsbKeyWords, * PUsbKeyWords;
GScanO200::GScanO200() :
huagods(NULL),
m_bread_fixed_ratio_fromDSP(false)
{
m_pImages.reset(new ImageMatQueue());
}
GScanO200::~GScanO200()
{
if (m_threadUsb && m_threadUsb->joinable()) {
devState = DEV_STOP;
m_threadUsb->join();
m_threadUsb.reset();
}
if(m_usb.get())
m_usb.reset();
}
void GScanO200::open(int vid, int pid)
{
auto usbs = UsbScan_List::find_vid_pid(vid, pid);
if (!usbs.empty()) {
}
else
{
int ivid, ipid;
#ifdef G200
#ifdef ISG100
ivid = 0x3072;
ipid = 0x0100;
#else
ivid = 0x3072;
ipid = 0x0200;
#endif // ISG100
#elif defined(G300)
ivid = 0x3072;
ipid = 0x0300;
#elif defined(G400)
ivid = 0x3072;
ipid = 0x0400;
#endif // G200
usbs = UsbScan_List::find_vid_pid(ivid, ipid);
}
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 GScanO200::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 GScanO200::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 GScanO200::IsConnected()
{
return m_usb.get() && m_usb->is_connected();
}
std::string GScanO200::GetFWVersion()
{
if (m_usb.get() && m_usb->is_connected()) {
lock_guard< mutex> lock(m_imgLocker);
if (fwVersion.empty()) {
#ifndef G200
fwVersion.resize(10);
#else // !G200
fwVersion.resize(8);
#endif
USBCB cmd = { GET_FW_VERSION,fwVersion.size(),0, };
m_usb->write_bulk(&cmd, sizeof(cmd));
m_usb->read_bulk(&fwVersion[0], fwVersion.size());
#ifdef G200
std::string ver = fwVersion.substr((fwVersion.length() - 2), 2);
int verValue = atoi(ver.c_str());
m_bread_fixed_ratio_fromDSP = verValue >= 15;
//writelog(m_bread_fixed_ratio_fromDSP ? "can get ratio from dsp" : "can not get dsp ratio");
updateHVRatio();
#endif // G200
}
;
return fwVersion;
}
return "";
}
std::string GScanO200::GetSerialNum()
{
//return "G20018000298";
if (m_usb.get() && m_usb->is_connected())
{
std::lock_guard<std::mutex> lck(m_imgLocker);
if (SerialNum.empty()) {
#ifndef G200
SerialNum.resize(14);
#else // !G200
SerialNum.resize(12);
#endif
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 GScanO200::is_scan()
{
//std::lock_guard<std::mutex> lck(m_imgLocker);
return devState == DEV_ISRUNNING;
}
BOOL GScanO200::Get_Scanner_PaperOn()
{
if (m_usb.get() && !m_usb->is_open())
return false;
USBCB usbcb = { GET_PAPER_STATUS ,0,0 };
std::lock_guard<std::mutex> lck(m_imgLocker);
m_usb->write_bulk(&usbcb, sizeof(usbcb));
m_usb->read_bulk(&usbcb, sizeof(usbcb));
return usbcb.u32_Data != 0;
}
void GScanO200::config_params(GScanCap& params)
{
if (m_usb.get() && m_usb->is_connected()) {
#ifndef G200
G400ScanConfig cfg = G400ScanConfig(params);
#else
hgConfigClass cfg = hgConfigClass(params);
#endif
gcap = params;
UINT32 cfgdata = cfg.GetData();
USBCB usbcb = { CONFIGURED_DATA,cfgdata,0 };
m_usb->write_bulk(&usbcb, sizeof(USBCB));
this_thread::sleep_for(std::chrono::milliseconds(200));
m_pImages->setparam(params);
}
}
void GScanO200::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;
}
//#ifndef G200
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())
m_usb->read_bulk(&paperstatus, sizeof(paperstatus));
if (paperstatus.u32_Data == 0) {
m_pImages->setscanflags(false);
devState = DEV_WRONG;
Set_ErrorCode(NO_FEED);
if (huagods)
dev_callback(NO_FEED, huagods);
return;
}
//#endif // !G200
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(&GScanO200::usbmain, this));
m_pImages->run();
}
}
void GScanO200::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 GScanO200::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 GScanO200::Get_IsImageQueueEmpty()
{
return m_pImages->empty();
}
void GScanO200::reset()
{
while (!m_pImages->empty())
m_pImages->clear();
}
void GScanO200::setdecodepixtype(int twpixtype)
{
}
UINT32 GScanO200::get_ErrorCode()
{
return Error_Code;
}
void GScanO200::Set_ErrorCode(UINT32 value)
{
Error_Code = value;
}
int GScanO200::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 GScanO200::clear_hwerror()
{
#ifndef G200
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));
#endif // !G200
}
void GScanO200::usbhotplug_callback(bool isconnect, void* userdata)
{
GScanO200* This = (GScanO200*)userdata;
This->usbhotplug(isconnect);
}
void GScanO200::usbhotplug(bool isleft)
{
if (isleft) {
//std::lock_guard<std::mutex> lck(m_Locker);
//FileTools::
//("D:\\1.txt", "usbhotplug left");
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 GScanO200::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));
//writelog("fx: " + to_string(hratio) + " fy :" + to_string(vratio));
m_pImages->updatefixratio(hratio, vratio);
}
}
void GScanO200::usbmain()
{
std::shared_ptr<std::vector<char>> imgData;
devState = DEV_ISRUNNING;
bool haveError = false;
////FileTools::write_log("D:\\1.txt", "thread usb start");
try
{
StopWatch sw;
while (devState == DEV_ISRUNNING) {
if ((m_usb.get() && !m_usb->is_connected())) {
this_thread::sleep_for(chrono::milliseconds(200));
//FileTools::write_log("D:\\1.txt", "thread usb loop disconnect");
break;
}
////FileTools::write_log("D:\\1.txt", "thread usb start1");
//if (gcap.resolution_dst == 300.0f && gcap.en_fold) {
// if (m_pImages->orginimgcount() > 1)
// {
// this_thread::sleep_for(chrono::milliseconds(100));
// continue;
// }
//}
if (sw.elapsed_ms() > 10000)
{
m_pImages->setscanflags(false);
devState = haveError ? DevState::DEV_WRONG : DevState::DEV_STOP;
return;
}
if (gcap.resolution_dst >= 300.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;
}
m_pImages->pushMat(std::shared_ptr<IDecode>(new G200Decode(imgData)));
//static int rawdataindex = 0;
//writelog("origin rawbuffer index " + std::to_string(++rawdataindex));
#ifdef LOG_NORMAL
static int rawdataindex = 0;
//FileTools::write_log("out.txt", "Enquque rawbuffer index " + std::to_string(++rawdataindex));
#endif // LOG
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:
#ifdef G200
Set_ErrorCode(usbcb.u32_Data);
m_pImages->setscanflags(false);
devState = DEV_WRONG;
if (huagods)
dev_callback(usbcb.u32_Data, huagods);
#else
if (!haveError)
{
haveError = true;
Set_ErrorCode(usbcb.u32_Data);
if (huagods)
dev_callback(usbcb.u32_Data, huagods);
}
#endif
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 GScanO200::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>> GScanO200::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;
while (readed < bufferSize && sw.elapsed_ms() < 5000) {
USBCB usbcb = { GET_IMAGE,0,(UINT32)bufferSize };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
readed = m_usb->read_bulk(imData->data(), bufferSize);
}
if (sw.elapsed_ms() > 3000) {
writelog("Usb read data timeout\n");
}
return imData;
}
///////////////////////////////////////////////////////////////////////////
void GScanO200::Pop_Image()
{
if (m_usb.get() && !m_usb->is_open())
return;
USBCB usbcb = { POP_IMAGE ,0,0 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
}