twain3/device/GScanO3399.cpp

390 lines
6.6 KiB
C++
Raw Permalink Blame History

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