twain3.0/huagao/Device/GScanO200.cpp

396 lines
8.5 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 "stdafx.h"
#include "GScanO200.h"
#include "UsbScanEx.h"
#include "UsbScanEx.h"
#include "StopWatch.h"
#include "scn_config.h"
#include "ImageMatQueue.h"
#include "filetools.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
} UsbKeyWords, * PUsbKeyWords;
GScanO200::GScanO200()
{
}
GScanO200::~GScanO200()
{
if (m_threadUsb && m_threadUsb->joinable()) {
devState = DEV_STOP;
m_threadUsb->join();
m_threadUsb.reset();
}
}
void GScanO200::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();
if (ret) {
m_usb->set_usbhotplug_callback(usbhotplug_callback, this);
}
}
}
#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();
}
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();
#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()) {
fwVersion = " ";
USBCB cmd= { GET_FW_VERSION,8,0,};
m_usb->write_bulk(&cmd, sizeof(cmd));
m_usb->read_bulk(&fwVersion[0], 8);
}
return fwVersion;
}
return "";
}
std::string GScanO200::GetSerialNum()
{
if (m_usb.get() && m_usb->is_connected())
{
std::lock_guard<mutex> lck(m_imgLocker);
if (SerialNum.empty()) {
SerialNum = " ";
USBCB usbcb = { GET_SERIAL,12,0 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
m_usb->read_bulk(&SerialNum[0], 12);
}
return SerialNum;
}
return "";
}
bool GScanO200::is_scan()
{
//std::lock_guard<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<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()) {
IConfig cfg;
cfg = hgConfigClass(params);
UINT32 cfgdata = cfg.GetData();
USBCB usbcb = { CONFIGURED_DATA,cfgdata,0 };
m_usb->write_bulk(&usbcb, sizeof(USBCB));
m_pImages->setparam(params);
}
}
void GScanO200::Scanner_StartScan(UINT16 count)
{
if (m_usb.get() && m_usb->is_connected()) {
std::lock_guard<mutex> lck(m_imgLocker);
USBCB usbcb = { START_COMMAND,(UINT32)count ,0 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
if (m_threadUsb && m_threadUsb->joinable()) {
m_threadUsb->join();
}
m_threadUsb.reset(new thread(&GScanO200::usbmain, this));
m_pImages->run();
m_pImages->setscanflags(true);
}
}
void GScanO200::Stop_scan()
{
if (m_usb.get() && !m_usb->is_connected()) {
return;
}
std::lock_guard<mutex> lck(m_imgLocker);
USBCB usbcb = { STOP ,0,0 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
}
void GScanO200::ResetScanner()
{
if (m_usb.get() && !m_usb->is_connected())
return;
std::lock_guard<mutex> lck(m_imgLocker);
USBCB usbcb = { INIT_HARDWARE_SYS ,0,0 };
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()
{
if (m_usb.get() && !m_usb->is_connected())
return -1;
std::lock_guard<mutex> lck(m_imgLocker);
USBCB usbcb = { GET_SCANN_NUM ,0,0 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
return usbcb.u32_Count;
}
void GScanO200::usbhotplug_callback(bool isconnect, void* userdata)
{
GScanO200* This = (GScanO200*)userdata;
This->usbhotplug(isconnect);
}
void GScanO200::usbhotplug(bool isleft)
{
if (isleft) {
//devState = DEV_WRONG;
//Error_Code = USB_DISCONNECTED;
//m_pImages->setscanflags(false);
}
}
void GScanO200::usbmain()
{
std::shared_ptr<std::vector<char>> imgData;
devState = DEV_ISRUNNING;
while (devState == DEV_ISRUNNING) {
if (m_usb.get() && !m_usb->is_connected()) {
this_thread::sleep_for(chrono::milliseconds(200));
continue;
}
USBCB usbcb = Get_Scanner_Status();
switch (usbcb.u32_Data) {
case HAVE_IMAGE:
{
int totalNum = usbcb.u32_Count;
m_usb->set_timeout(1500);
imgData = Get_Img_Data(totalNum);
if (!imgData->size()) {
Stop_scan();
}
m_pImages->pushMat(std::shared_ptr<IDecode>(new G200Decode(imgData)));
#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();
break;
}
case STOP_SCAN:
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:
Set_ErrorCode(usbcb.u32_Data);
m_pImages->setscanflags(false);
devState = DEV_WRONG;
break;
case NORMAL:
break;
default:
break;
}
this_thread::sleep_for(chrono::milliseconds(20));
}
}
///////////////////////////////////////////////////////////////////////////
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 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
m_usb->read_bulk(&usbcb, sizeof(usbcb));
return usbcb;
}
std::shared_ptr<std::vector<char>> GScanO200::Get_Img_Data(int bufferSize)
{
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 error\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));
}