mirror of http://192.168.1.51:8099/lmh188/twain3.0
822 lines
21 KiB
C++
822 lines
21 KiB
C++
#include "stdafx.h"
|
||
#include "GScanO400Android.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 = 0x42,
|
||
//设置扫描仪编码
|
||
GET_CODE_G400 = 0x59,
|
||
//读取扫描仪编码
|
||
SET_CODE_G400 = 0x60,
|
||
//设置扫描仪编码
|
||
SET_CODE_G200 = 0x63,
|
||
//读取扫描仪编码
|
||
GET_CODE_G200 = 0x64,
|
||
|
||
} UsbKeyWords, * PUsbKeyWords;
|
||
|
||
GScanO400Android::GScanO400Android() :
|
||
huagods(NULL),
|
||
image_num(0),
|
||
m_bread_fixed_ratio_fromDSP(false)
|
||
{
|
||
m_pImages.reset(new ImageMatQueue());
|
||
auto getimgnum = [&](bool isadd, int num)
|
||
{
|
||
isadd ? image_num += num : image_num -= num;
|
||
};
|
||
m_pImages->SetGetimgnumcall(getimgnum);
|
||
}
|
||
|
||
GScanO400Android::~GScanO400Android()
|
||
{
|
||
if (m_threadUsb && m_threadUsb->joinable()) {
|
||
devState = DEV_STOP;
|
||
m_threadUsb->join();
|
||
m_threadUsb.reset();
|
||
}
|
||
if (m_usb.get())
|
||
m_usb.reset();
|
||
|
||
}
|
||
|
||
void GScanO400Android::DogEar_callback(std::function<void(int)> fun)
|
||
{
|
||
m_pImages->SetDogEarCallback(fun);
|
||
}
|
||
|
||
void GScanO400Android::open(int vid, int pid)
|
||
{
|
||
auto usbs = UsbScan_List::find_vid_pid(vid, pid);
|
||
|
||
if (!usbs.empty())
|
||
{
|
||
m_usb = *usbs.begin();
|
||
m_usb->set_usbhotplug_callback(usbhotplug_callback, this);
|
||
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));
|
||
//m_usb->read_bulk(&status, sizeof(status));
|
||
//std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||
//notifyscan();
|
||
GetFWVersion();
|
||
}
|
||
}
|
||
}
|
||
|
||
void GScanO400Android::regist_deviceevent_callback(deviceevent_callback callback, void* usrdata)
|
||
{
|
||
huagods = usrdata;
|
||
dev_callback = callback;
|
||
}
|
||
|
||
int GScanO400Android::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() > 30.00)
|
||
{
|
||
int roller_num_new = Get_Roller_num();
|
||
if (m_threadUsb && m_threadUsb->joinable()) {
|
||
devState = DEV_STOP;
|
||
m_threadUsb->join();
|
||
m_threadUsb.reset();
|
||
FileTools::writelog(log_ERROR, "aquire_bmpdata m_threadUsb.reset()");
|
||
}
|
||
Stop_scan();//停止扫描
|
||
ResetScanner();
|
||
set_scannum(abs(roller_num_new - roller_num));
|
||
return HARDWARE_ERROR;
|
||
}
|
||
|
||
if (!is_scan()) {
|
||
int roller_num_new = Get_Roller_num();
|
||
set_scannum(abs(roller_num_new - roller_num));
|
||
if (devState == DEV_WRONG) {
|
||
return get_ErrorCode();
|
||
}
|
||
return -1;
|
||
}
|
||
}
|
||
else {
|
||
if (m_pImages->valid()) {
|
||
bmpdata = *(m_pImages->popBmpdata());
|
||
UpdateScanInfo(get_imgnReaded(), countNTransfered());
|
||
return 0;
|
||
}
|
||
DoEvents();
|
||
this_thread::sleep_for(chrono::milliseconds(2));
|
||
}
|
||
}
|
||
}
|
||
|
||
BOOL GScanO400Android::IsConnected()
|
||
{
|
||
return m_usb.get() && m_usb->is_connected();
|
||
}
|
||
|
||
std::string GScanO400Android::GetMacAdder() {
|
||
return "固件版本不支持读取";
|
||
}
|
||
|
||
std::string GScanO400Android::GetFWVersion()
|
||
{
|
||
//return "1234567890";
|
||
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));
|
||
std::this_thread::sleep_for(chrono::milliseconds(10));
|
||
if (m_usb.get() && m_usb->is_connected())
|
||
m_usb->read_bulk(&fwVersion[0], fwVersion.size());
|
||
std::this_thread::sleep_for(chrono::milliseconds(10));
|
||
}
|
||
return fwVersion;
|
||
}
|
||
return "";
|
||
}
|
||
|
||
std::string GScanO400Android::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));
|
||
if (m_usb.get() && m_usb->is_connected())
|
||
m_usb->read_bulk(&SerialNum[0], SerialNum.size());
|
||
}
|
||
return SerialNum;
|
||
}
|
||
return "";
|
||
}
|
||
|
||
std::uint32_t GScanO400Android::GetMotorFPGA()
|
||
{
|
||
if (m_usb.get() && m_usb->is_connected())
|
||
{
|
||
std::lock_guard<std::mutex> lck(m_imgLocker);
|
||
USBCB usbcb = { GET_MOTORFPGA_VERSION,0,sizeof(MotorFpga) };
|
||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||
m_usb->read_bulk(&usbcb, sizeof(usbcb));
|
||
MotorFpga = usbcb.u32_Data;
|
||
return MotorFpga;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
std::uint32_t GScanO400Android::GetScanFPGA()
|
||
{
|
||
if (m_usb.get() && m_usb->is_connected())
|
||
{
|
||
std::lock_guard<std::mutex> lck(m_imgLocker);
|
||
USBCB usbcb = { GET_SCANFPGA_VERSION,0,4 };
|
||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||
m_usb->read_bulk(&usbcb, sizeof(usbcb));
|
||
ScanFpga = usbcb.u32_Data;
|
||
return ScanFpga;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
bool GScanO400Android::is_scan()
|
||
{
|
||
//std::lock_guard<std::mutex> lck(m_imgLocker);
|
||
return devState == DEV_ISRUNNING;
|
||
}
|
||
|
||
BOOL GScanO400Android::Get_Scanner_PaperOn()
|
||
{
|
||
if (!(m_usb.get() && m_usb->is_open()))
|
||
{
|
||
Set_ErrorCode(USB_DISCONNECTED);
|
||
return true;
|
||
}
|
||
|
||
USBCB usbcb = { GET_PAPER_STATUS ,2,0 };
|
||
std::lock_guard<std::mutex> lck(m_imgLocker);
|
||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||
if (m_usb.get() && m_usb->is_connected()) {
|
||
m_usb->read_bulk(&usbcb, sizeof(usbcb));
|
||
if (usbcb.u32_Data == 2)
|
||
{
|
||
Set_ErrorCode(USB_DISCONNECTED);
|
||
return true;
|
||
}
|
||
}
|
||
else {
|
||
Set_ErrorCode(USB_DISCONNECTED);
|
||
return true;
|
||
}
|
||
return usbcb.u32_Data != 0;
|
||
}
|
||
|
||
int GScanO400Android::Get_Roller_num()
|
||
{
|
||
if (!(m_usb.get() && m_usb->is_open()))
|
||
return false;
|
||
USBCB usbcb = { GET_SCANN_NUM ,0,4 };
|
||
std::lock_guard<std::mutex> lck(m_imgLocker);
|
||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||
m_usb->read_bulk(&usbcb, sizeof(usbcb));
|
||
if (usbcb.u32_CMD != GET_SCANN_NUM)
|
||
{
|
||
FileTools::writelog(log_ERROR, "get roller usb bulk error");
|
||
}
|
||
FileTools::writelog(log_INFO, "get roller num " + to_string(usbcb.u32_Data));
|
||
return usbcb.u32_Data;
|
||
}
|
||
|
||
void GScanO400Android::config_params(GScanCap& params)
|
||
{
|
||
|
||
if (m_usb.get() && m_usb->is_connected()) {
|
||
G400AndroidScanConfig cfg = G400AndroidScanConfig(params);
|
||
gcap = params;
|
||
UINT32 cfgdata = cfg.GetData();
|
||
USBCB usbcb = { CONFIGURED_DATA,cfgdata,0 };
|
||
FileTools::writelog(log_INFO, "config hardware param" + to_string(cfgdata));
|
||
m_usb->write_bulk(&usbcb, sizeof(USBCB));
|
||
this_thread::sleep_for(std::chrono::milliseconds(200));
|
||
params.resolution_native = 200.0f;
|
||
m_pImages->setparam(params);
|
||
}
|
||
}
|
||
|
||
void GScanO400Android::Scanner_StartScan(UINT16 count)
|
||
{
|
||
scanfalg = false;
|
||
Set_ErrorCode(0);
|
||
roller_num = Get_Roller_num();
|
||
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(&GScanO400Android::usbmain, this));
|
||
m_pImages->run();
|
||
}
|
||
}
|
||
|
||
int GScanO400Android::notifyscan()
|
||
{
|
||
//if (!m_usb.get() && !m_usb->is_connected())
|
||
// return -1;
|
||
//USBCB notify = { 0x100,0,0 };
|
||
//m_usb->write_bulk(¬ify, sizeof(notify));
|
||
//m_usb->read_bulk(¬ify, sizeof(notify));
|
||
//if ((notify.u32_Data != 0x10 && GetFWVersion().length() < 10) || notify.u32_Data == 0x100)
|
||
//{
|
||
// ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("扫描仪处于休眠状态,请按电源键唤醒! 提示 "), NULL, SW_HIDE);
|
||
// return -1;
|
||
//}
|
||
return 1;
|
||
}
|
||
|
||
|
||
void GScanO400Android::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));
|
||
scanfalg = true;
|
||
FileTools::writelog(log_INFO, "user stop scan");
|
||
}
|
||
}
|
||
|
||
|
||
void GScanO400Android::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 GScanO400Android::Get_IsImageQueueEmpty()
|
||
{
|
||
return m_pImages->empty();
|
||
}
|
||
|
||
void GScanO400Android::reset()
|
||
{
|
||
while (!m_pImages->empty())
|
||
m_pImages->clear();
|
||
}
|
||
|
||
|
||
UINT32 GScanO400Android::get_ErrorCode()
|
||
{
|
||
return Error_Code;
|
||
}
|
||
|
||
void GScanO400Android::Set_ErrorCode(UINT32 value)
|
||
{
|
||
Error_Code = value;
|
||
}
|
||
|
||
int GScanO400Android::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 GScanO400Android::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 GScanO400Android::set_sleep_time(int mode)
|
||
{
|
||
return;
|
||
}
|
||
|
||
bool GScanO400Android::set_scannercode(std::string str)
|
||
{
|
||
if (str.size() != 32)
|
||
return false;
|
||
if (!(m_usb.get() && m_usb->is_connected()))
|
||
return false;
|
||
for (int i = 0; i < str.size(); i += 4)
|
||
{
|
||
USBCB usbcb = { SET_CODE_G400,UINT32(str[i]) + ((UINT32(str[i + 1])) << 8) + (((UINT32)str[i + 2]) << 16) + (((UINT32)str[i + 3]) << 24),i };
|
||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||
}
|
||
return true;
|
||
}
|
||
|
||
std::string GScanO400Android::get_scannercode()
|
||
{
|
||
if (!(m_usb.get() && m_usb->is_connected()))
|
||
return NULL;
|
||
USBCB usb{ GET_CODE_G400,0,32 };
|
||
m_usb->write_bulk(&usb, sizeof(USBCB));
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||
scannercode.resize(32);
|
||
m_usb->read_bulk(&scannercode[0], 32);
|
||
return scannercode.c_str();
|
||
}
|
||
|
||
void GScanO400Android::usbhotplug_callback(bool isconnect, void* userdata)
|
||
{
|
||
GScanO400Android* This = (GScanO400Android*)userdata;
|
||
This->usbhotplug(isconnect);
|
||
}
|
||
|
||
void GScanO400Android::usbhotplug(bool isleft)
|
||
{
|
||
FileTools::writelog(log_ERROR, "enable usb callback ");
|
||
if (isleft) {
|
||
devState = DEV_WRONG;
|
||
Error_Code = USB_DISCONNECTED;
|
||
image_last = false;
|
||
m_pImages->setscanflags(false);
|
||
if (m_usb.get())
|
||
m_usb.reset();
|
||
if (huagods)
|
||
dev_callback(USB_DISCONNECTED, huagods);
|
||
}
|
||
}
|
||
|
||
void GScanO400Android::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 GScanO400Android::usbmain()
|
||
{
|
||
std::shared_ptr<std::vector<char>> imgData;
|
||
devState = DEV_ISRUNNING;
|
||
image_last = true;
|
||
bool haveError = false;
|
||
bool is_first_error = true;
|
||
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() > 30000)
|
||
{
|
||
m_pImages->setscanflags(false);
|
||
Set_ErrorCode(AQUIRE_IMAGE_TIMEOUT);
|
||
devState = DevState::DEV_WRONG;
|
||
//devState = haveError ? DevState::DEV_WRONG : DevState::DEV_STOP;
|
||
FileTools::writelog(log_ERROR, "USBmain aquire image timeout");
|
||
return;
|
||
}
|
||
|
||
USBCB usbcb = Get_Scanner_Status();
|
||
switch (usbcb.u32_Data) {
|
||
case HAVE_IMAGE:
|
||
{
|
||
is_first_error = false;
|
||
int totalNum = usbcb.u32_Count&0x3fffffff;
|
||
if ((usbcb.u32_Count & 0xc0000000) == 0)
|
||
{
|
||
image_last = false;
|
||
}
|
||
if (totalNum < 1)
|
||
{
|
||
image_last = false;
|
||
break;
|
||
}
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||
m_usb->set_timeout(2000);
|
||
imgData = Get_Img_Data(totalNum);
|
||
m_usb->set_timeout(200);
|
||
if (!imgData->size()) {
|
||
Stop_scan();
|
||
FileTools::writelog(log_ERROR, "imgData->size() error");
|
||
break;
|
||
}
|
||
FileTools::writelog(log_INFO, " get image data size " + to_string(totalNum));
|
||
if (imgData->size() != totalNum)
|
||
{
|
||
FileTools::writelog(log_ERROR, " get image data size error totalnum " + to_string(totalNum) + " imgdata size " + to_string(imgData->size()));
|
||
}
|
||
if (!m_pImages->get_isDogEar())
|
||
m_pImages->pushMat(std::shared_ptr<IDecode>(new G400Decode(imgData)));
|
||
|
||
UpdateScanInfo(countNReaded(), get_imgTransfered());
|
||
FileTools::writelog(log_INFO, "从扫描仪接收" + to_string(get_imgnReaded()) + "份文件。耗时 " + to_string(sw.elapsed_ms()));
|
||
sw.reset();
|
||
break;
|
||
}
|
||
case STOP_SCAN:
|
||
{
|
||
//m_pImages->setscanflags(false);
|
||
//std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||
devState = haveError ? DevState::DEV_WRONG : DevState::DEV_STOP;
|
||
if (is_first_error)
|
||
image_last = false;
|
||
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:
|
||
case USB_BULK_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));
|
||
}
|
||
|
||
while (image_last)
|
||
{
|
||
auto usbcb = Get_Scanner_Status();
|
||
if (usbcb.u32_Data != 0x47)
|
||
{
|
||
this_thread::sleep_for(chrono::milliseconds(10));
|
||
continue;
|
||
}
|
||
int totalNum = usbcb.u32_Count & 0x3fffffff;
|
||
if (totalNum < 1)
|
||
{
|
||
image_last = false;
|
||
break;
|
||
}
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||
m_usb->set_timeout(2000);
|
||
imgData = Get_Img_Data(totalNum);
|
||
m_usb->set_timeout(200);
|
||
if (!imgData->size()) {
|
||
Stop_scan();
|
||
FileTools::writelog(log_ERROR, "imgData->size() error");
|
||
break;
|
||
}
|
||
FileTools::writelog(log_INFO, " get image data size " + to_string(totalNum));
|
||
if (imgData->size() != totalNum)
|
||
{
|
||
FileTools::writelog(log_ERROR, " get image data size error totalnum " + to_string(totalNum) + " imgdata size " + to_string(imgData->size()));
|
||
}
|
||
if (!m_pImages->get_isDogEar())
|
||
m_pImages->pushMat(std::shared_ptr<IDecode>(new G400Decode(imgData)));
|
||
UpdateScanInfo(countNReaded(), get_imgTransfered());
|
||
FileTools::writelog(log_INFO, "从扫描仪接收" + to_string(get_imgnReaded()) + "份文件。耗时 " + to_string(sw.elapsed_ms()));
|
||
}
|
||
m_pImages->setscanflags(false);
|
||
|
||
}
|
||
catch (const std::exception& e)
|
||
{
|
||
FileTools::writelog(log_ERROR, e.what());
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
USBCB GScanO400Android::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));
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||
if (m_usb.get() && m_usb->is_connected())
|
||
m_usb->read_bulk(&usbcb, sizeof(usbcb));
|
||
//if (usbcb.u32_CMD != GET_DSP_STATUS)
|
||
//{
|
||
// std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||
// if (m_usb.get() && m_usb->is_connected())
|
||
// m_usb->read_bulk(&usbcb, 512);
|
||
// FileTools::writelog(log_ERROR, "get dsp status error");
|
||
// //return { NO_COMMAND,USB_BULK_ERROR,0 };
|
||
//}
|
||
return usbcb;
|
||
}
|
||
|
||
std::shared_ptr<std::vector<char>> GScanO400Android::Get_Img_Data(int bufferSize)
|
||
{
|
||
try
|
||
{
|
||
bool ZLP = false;
|
||
if (!(m_usb.get() && m_usb->is_connected()))
|
||
return std::shared_ptr<std::vector<char>>(new std::vector<char>());
|
||
if ((bufferSize & 511) == 0)
|
||
{
|
||
bufferSize += 1;
|
||
ZLP = true;
|
||
}
|
||
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));
|
||
this_thread::sleep_for(chrono::milliseconds(50));
|
||
int totalength = 512 * 1024;
|
||
int startindex = 0;
|
||
std::this_thread::sleep_for(std::chrono::microseconds(20));
|
||
while (startindex < bufferSize)
|
||
{
|
||
startindex += m_usb->read_bulk(imData->data() + startindex, (bufferSize - startindex) < totalength ? (bufferSize - startindex) : totalength); //数据接收量必须小于等于管道内数据量,否则会接收失败
|
||
std::this_thread::sleep_for(std::chrono::microseconds(10));
|
||
if (ZLP &&(startindex == (bufferSize - 1)))
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
if (sw.elapsed_ms() > 5000)
|
||
{
|
||
FileTools::writelog(log_ERROR, "Usb read data timeout\n");
|
||
}
|
||
return imData;
|
||
}
|
||
catch (const std::exception& e)
|
||
{
|
||
FileTools::writelog(log_ERROR, e.what());
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
void GScanO400Android::Pop_Image()
|
||
{
|
||
if (!(m_usb.get() && m_usb->is_open()))
|
||
return;
|
||
|
||
USBCB usbcb = { POP_IMAGE ,0,0 };
|
||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||
}
|
||
|