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
|
||
} |