mirror of http://192.168.1.51:8099/lmh188/twain3
390 lines
6.6 KiB
C++
390 lines
6.6 KiB
C++
|
#include "GScanO3399.h"
|
|||
|
#include <iostream>
|
|||
|
#include "StopWatch.h"
|
|||
|
#include <cmath>
|
|||
|
#include "usb/CyUsbEx.h"
|
|||
|
#include "UsbLists.h"
|
|||
|
#include "ImageMatQueue.h"
|
|||
|
|
|||
|
#define USB_REQ_GET_FPGA_REGS 0x40
|
|||
|
#define USB_REQ_SET_FPGA_REGS 0x41
|
|||
|
#define USB_REQ_GET_MOTOR_REGS 0x42
|
|||
|
#define USB_REQ_SET_MOTOR_REGS 0x43
|
|||
|
|
|||
|
#define USB_REQ_GET_DEV_STATUS 0x60
|
|||
|
#define USB_REQ_GET_DEV_CONFIGURATION 0x61
|
|||
|
#define USB_REQ_SET_DEV_CONFIGURATION 0x62
|
|||
|
#define USB_REQ_GET_DEV_REGS 0x63
|
|||
|
#define USB_REQ_SET_DEV_REGS 0x64
|
|||
|
|
|||
|
enum Scanner_Reg_Defs
|
|||
|
{
|
|||
|
SR_CMD,
|
|||
|
SR_STATUS,
|
|||
|
SR_SCAN_COUNT,
|
|||
|
SR_OS,
|
|||
|
SR_SENSORS,
|
|||
|
SR_MOTOR,
|
|||
|
SR_IM_TYPE,
|
|||
|
SR_IM_COUNT,
|
|||
|
SR_IM_TX,
|
|||
|
SR_IM_FRONT_SIZE,
|
|||
|
SR_IM_CLEAR,
|
|||
|
SR_IM_TXING,
|
|||
|
SR_IM_POP,
|
|||
|
SR_IM_ABORT,
|
|||
|
SR_COUNT
|
|||
|
};
|
|||
|
|
|||
|
enum Scanner_Cmd_Defs
|
|||
|
{
|
|||
|
SC_START,
|
|||
|
SC_STOP,
|
|||
|
SC_CLEAR,
|
|||
|
SC_COUNT
|
|||
|
};
|
|||
|
|
|||
|
static std::mutex mx_ctrl;
|
|||
|
|
|||
|
static int scanner_read_reg(std::shared_ptr<IUsb>& usb, int addr)
|
|||
|
{
|
|||
|
int val = 0;
|
|||
|
std::lock_guard<std::mutex> lck(mx_ctrl);
|
|||
|
usb->control_msg(0xc0, USB_REQ_GET_DEV_REGS, addr, 0, 4, &val);
|
|||
|
return val;
|
|||
|
}
|
|||
|
|
|||
|
static void scanner_write_reg(std::shared_ptr<IUsb>& usb, int addr, int val)
|
|||
|
{
|
|||
|
std::lock_guard<std::mutex> lck(mx_ctrl);
|
|||
|
usb->control_msg(0x40, USB_REQ_SET_DEV_REGS, addr, 0, 4, &val);
|
|||
|
}
|
|||
|
|
|||
|
static void scanner_cmd(std::shared_ptr<IUsb>& usb, int cmd)
|
|||
|
{
|
|||
|
scanner_write_reg(usb, 0, cmd);
|
|||
|
}
|
|||
|
|
|||
|
Scanner::Scanner()
|
|||
|
:thpool(1)
|
|||
|
,thpoolRx(1)
|
|||
|
{
|
|||
|
auto usbls = CyUsbList::find_all();
|
|||
|
if (!usbls.empty())
|
|||
|
{
|
|||
|
this->usb = *usbls.begin();
|
|||
|
this->usb->open();
|
|||
|
b_fu_int = true;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
Scanner::~Scanner()
|
|||
|
{
|
|||
|
b_fu_int = false;
|
|||
|
if (fu_rx.valid())
|
|||
|
fu_rx.wait();
|
|||
|
b_fu_rx = false;
|
|||
|
if (fu_rx.valid())
|
|||
|
fu_rx.wait();
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::start()
|
|||
|
{
|
|||
|
scanner_cmd(usb, SC_START);
|
|||
|
fu_int = thpool.enqueue(&Scanner::int_run, this);
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::stop()
|
|||
|
{
|
|||
|
scanner_cmd(usb , SC_STOP);
|
|||
|
}
|
|||
|
|
|||
|
bool Scanner::is_runing()
|
|||
|
{
|
|||
|
return scanner_read_reg(usb, SR_STATUS);
|
|||
|
}
|
|||
|
|
|||
|
int Scanner::mode()
|
|||
|
{
|
|||
|
return scanner_read_reg(usb, SR_STATUS) & 0x02;
|
|||
|
}
|
|||
|
|
|||
|
bool Scanner::rx_cmd()
|
|||
|
{
|
|||
|
scanner_write_reg(usb, 8, 1);
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
int Scanner::count()
|
|||
|
{
|
|||
|
return scanner_read_reg(usb, SR_SCAN_COUNT);
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::setdecodepixtype(int twpixtype)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
UINT32 Scanner::get_ErrorCode()
|
|||
|
{
|
|||
|
return UINT32();
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::Set_ErrorCode(UINT32 value)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
int Scanner::get_scanned_num()
|
|||
|
{
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
int Scanner::get_roller_num()
|
|||
|
{
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::clr_roller_num()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
int Scanner::get_sleep_time()
|
|||
|
{
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::set_sleep_time(int time)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
bool Scanner::clr_hardware_cache()
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::int_run()
|
|||
|
{
|
|||
|
unsigned char buff[64];
|
|||
|
bool brun = false;
|
|||
|
|
|||
|
while (b_fu_int)
|
|||
|
{
|
|||
|
if((usb->read_int(buff, sizeof(buff)) == sizeof(buff)) || im_dev_count())
|
|||
|
{
|
|||
|
if (is_runing())
|
|||
|
{
|
|||
|
if (!brun)
|
|||
|
brun = true;
|
|||
|
|
|||
|
im_rx();
|
|||
|
}
|
|||
|
/*else
|
|||
|
{
|
|||
|
devState = DEV_STOP;
|
|||
|
m_pImages->setscanflags(false);
|
|||
|
break;
|
|||
|
}*/
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if (!is_runing() && brun)
|
|||
|
{
|
|||
|
brun = false;
|
|||
|
devState = DEV_STOP;
|
|||
|
m_pImages->setscanflags(false);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int Scanner::read_data(void* data, int length, int timeout)
|
|||
|
{
|
|||
|
int readed = 0;
|
|||
|
int reading = 0;
|
|||
|
const int buffer_size = 2*1024*1024;
|
|||
|
StopWatch sw;
|
|||
|
while (readed < length && sw.elapsed_ms() < timeout) {
|
|||
|
reading = std::max(0, std::min(length - readed, buffer_size));
|
|||
|
reading = usb->read_bulk((unsigned char*)data + readed, reading);
|
|||
|
if (reading > 0) {
|
|||
|
readed += reading;
|
|||
|
}
|
|||
|
}
|
|||
|
return readed;
|
|||
|
}
|
|||
|
|
|||
|
int Scanner::front_datasize()
|
|||
|
{
|
|||
|
return scanner_read_reg(usb, SR_IM_FRONT_SIZE);
|
|||
|
}
|
|||
|
|
|||
|
bool Scanner::is_dev_tx()
|
|||
|
{
|
|||
|
return scanner_read_reg(usb, SR_IM_TXING);
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::abort_dev_tx()
|
|||
|
{
|
|||
|
scanner_write_reg(usb, SR_IM_ABORT, 1); //!< to-list
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::open(int vid, int pid)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
int Scanner::open(int vid)
|
|||
|
{
|
|||
|
return usb.get() ? 1:0;
|
|||
|
}
|
|||
|
|
|||
|
bool Scanner::close()
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
bool Scanner::is_open()
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::setusbreport_callback(usbreport_callback callback, void* usrdata)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
int Scanner::get_image_front_info(ImageInfo* info)
|
|||
|
{
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
int Scanner::aquire_image(cv::Mat& mat, int& bppinfo)
|
|||
|
{
|
|||
|
StopWatch sw;
|
|||
|
while (true)
|
|||
|
{
|
|||
|
if (m_pImages->empty()) {
|
|||
|
if (sw.elapsed_s() > 20.00)
|
|||
|
{
|
|||
|
Stop_scan();//ֹͣɨ<D6B9><C9A8>
|
|||
|
ResetScanner();
|
|||
|
return HARDWARE_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
if (!is_scan()) {
|
|||
|
if (devState == DEV_WRONG) {
|
|||
|
return get_ErrorCode();
|
|||
|
}
|
|||
|
return -1;
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
if (m_pImages->valid()) {
|
|||
|
auto ret = m_pImages->popimage();
|
|||
|
mat = ret.mat.clone();
|
|||
|
bppinfo = ret.Bpp;
|
|||
|
return 0;
|
|||
|
}
|
|||
|
#ifdef WIN32
|
|||
|
DoEvents();//<2F><>ֹUI<55><49><EFBFBD><EFBFBD>
|
|||
|
#endif // WIN32
|
|||
|
this_thread::sleep_for(chrono::milliseconds(1));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::clear_hwerror()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
bool Scanner::IsConnected()
|
|||
|
{
|
|||
|
return usb->is_connected();
|
|||
|
}
|
|||
|
|
|||
|
std::string Scanner::GetFWVersion(int mode)
|
|||
|
{
|
|||
|
return std::string();
|
|||
|
}
|
|||
|
|
|||
|
std::string Scanner::GetSerialNum(int mode)
|
|||
|
{
|
|||
|
return std::string();
|
|||
|
}
|
|||
|
|
|||
|
bool Scanner::is_scan()
|
|||
|
{
|
|||
|
return is_runing();
|
|||
|
}
|
|||
|
|
|||
|
bool Scanner::Get_Scanner_PaperOn()
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::config_params(GScanCap& params, int mode)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::Scanner_StartScan(UINT32 count, int mode)
|
|||
|
{
|
|||
|
devState = DEV_RUNNING;
|
|||
|
start();
|
|||
|
m_pImages->run();
|
|||
|
m_pImages->setscanflags(true);
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::Stop_scan()
|
|||
|
{
|
|||
|
stop();
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::ResetScanner()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void Scanner::reset()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
bool Scanner::Get_IsImageQueueEmpty()
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
bool Scanner::is_rx()
|
|||
|
{
|
|||
|
return fu_rx.valid() && (fu_rx.wait_for(std::chrono::seconds(0)) != std::future_status::ready);
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::im_rx()
|
|||
|
{
|
|||
|
|
|||
|
if (!is_rx() && !is_dev_tx())
|
|||
|
{
|
|||
|
fu_rx = thpoolRx.enqueue([this] {
|
|||
|
do
|
|||
|
{
|
|||
|
/* code */
|
|||
|
std::shared_ptr<std::vector<char>> buffi(new std::vector<char>);
|
|||
|
int count = front_datasize();
|
|||
|
buffi->resize(count);
|
|||
|
rx_cmd();
|
|||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|||
|
count = read_data(buffi->data(), count, count / (0.01 * 1024 * 1024));
|
|||
|
m_pImages->pushMat(std::shared_ptr<IDecode>(new GRawDecode(buffi)));
|
|||
|
pop_dev_im();
|
|||
|
}
|
|||
|
while (im_dev_count());
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void Scanner::pop_dev_im()
|
|||
|
{
|
|||
|
scanner_write_reg(usb, SR_IM_POP, 1); //!< to-list
|
|||
|
}
|
|||
|
|
|||
|
int Scanner::im_dev_count()
|
|||
|
{
|
|||
|
return scanner_read_reg(usb, SR_IM_COUNT); //!< to-list
|
|||
|
}
|