515 lines
13 KiB
C++
515 lines
13 KiB
C++
#include "UsbScanner.h"
|
||
#include <turbojpeg.h>
|
||
#include "JsonConfig.h"
|
||
#include "logs_out.h"
|
||
#include "JsonConfig.h"
|
||
#include "StopWatch.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_ACCES_DEV_LOG 0x50
|
||
|
||
#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
|
||
#define USB_REQ_GET_DEV_LOG 0x65
|
||
#define USB_REQ_SET_DEV_LOG 0x66
|
||
|
||
|
||
const int SPEED_MODE_MAX = 5;
|
||
UsbScanner::UsbScanner() : m_startscan(false),
|
||
imageremain(0),
|
||
eventsramain(0)
|
||
{
|
||
DeviceExport();
|
||
JsonConfig js;
|
||
ScannerScanInfo info = js.GetScanInfo();
|
||
|
||
pid_ = info.PID;
|
||
vid_ = info.VID;
|
||
m_serial = info.SerialNum;
|
||
m_fwversion = info.FWVersion;
|
||
|
||
printf("VID:%0x\r\n",vid_);
|
||
printf("PID:%0x\r\n",pid_);
|
||
printf("SerialNum:%s\r\n",m_serial.c_str());
|
||
printf("FWVersion:%s\r\n",m_fwversion.c_str());
|
||
mount_usb_device();
|
||
auto ctrl_req_handler = [&](int fd, struct usb_ctrlrequest *setup, unsigned char *buffer) -> bool
|
||
{
|
||
if (!(setup->bRequestType & USB_TYPE_VENDOR) || (setup->bRequestType & USB_RECIP_MASK) != USB_RECIP_DEVICE)
|
||
return false;
|
||
|
||
static std::string logstring;
|
||
unsigned int *regs = (unsigned int *)buffer;
|
||
int creg = 0;
|
||
if (!(setup->wLength % 4))
|
||
creg = setup->wLength / 4;
|
||
|
||
int regindex = setup->wValue;
|
||
|
||
switch (setup->bRequest)
|
||
{
|
||
case USB_REQ_GET_FPGA_REGS:
|
||
if ((setup->bRequestType & USB_DIR_IN) && creg)
|
||
{
|
||
if (regindex < 0 || regindex >= 18)
|
||
return false;
|
||
unsigned int regv = m_hgScanner->readreg(regindex);
|
||
memcpy(buffer, ®v, sizeof(regv));
|
||
::write(fd, buffer, setup->wLength);
|
||
return true;
|
||
}
|
||
break;
|
||
case USB_REQ_SET_FPGA_REGS:
|
||
if (!(setup->bRequestType & USB_DIR_IN) && creg)
|
||
{
|
||
::read(fd, buffer, setup->wLength);
|
||
|
||
LOG("USB_REQ_SET_FPGA_REGS set val = %d \n", *(unsigned int *)buffer);
|
||
// if (!write_regs(regs, regindex, creg, this->fgparegs))
|
||
// return false;
|
||
/*
|
||
暂时不响应上层配置fpga寄存器操作,仅将数据读出来;
|
||
*/
|
||
|
||
return true;
|
||
}
|
||
break;
|
||
|
||
case USB_REQ_GET_MOTOR_REGS:
|
||
if ((setup->bRequestType & USB_DIR_IN))
|
||
{
|
||
// if (!read_regs(regs, regindex, creg, this->motorregs))
|
||
// return false;
|
||
/*
|
||
无电机板寄存器,不响应;
|
||
*/
|
||
::write(fd, buffer, setup->wLength);
|
||
return true;
|
||
}
|
||
break;
|
||
case USB_REQ_SET_MOTOR_REGS:
|
||
if (!(setup->bRequestType & USB_DIR_IN))
|
||
{
|
||
::read(fd, buffer, setup->wLength);
|
||
// if (!write_regs(regs, regindex, creg, this->motorregs))
|
||
// return false;
|
||
/*
|
||
无电机板寄存器,不响应;
|
||
*/
|
||
return true;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
auto hotplug_handler = [&](bool isconnect)
|
||
{
|
||
printf("usb hotplug_handler is connect : %s \n", isconnect ? "true" : "false");
|
||
};
|
||
|
||
m_usb.reset(new UsbDevice(ctrl_req_handler, hotplug_handler));
|
||
StopWatch sw;
|
||
while (!m_usb->is_connected())
|
||
{
|
||
if(sw.elapsed_ms() >= 1000.0)
|
||
break;
|
||
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
||
}
|
||
|
||
auto imageready = [this](const HG_JpegCompressInfo &imageinfo)
|
||
{
|
||
imageremain++;
|
||
m_images.Put(imageinfo);
|
||
LOG("队列缓存张数:%d\r\n",m_images.Size());
|
||
};
|
||
|
||
auto deviceevent = [this](const int eventID, std::string capmsg)
|
||
{
|
||
printf("插入事件:%d\r\n",eventID);
|
||
eventsramain++;
|
||
m_scannerEvents.Put({eventID, capmsg});
|
||
if (eventID == (int)HG_ScannerStatus::STOP_SCAN)
|
||
{
|
||
m_startscan = false;
|
||
}
|
||
if (eventID == (int)(HG_ScannerStatus::AUTO_FLAT_FINISHED))
|
||
{
|
||
m_hgScanner->ResetCorrectflags();
|
||
}
|
||
else if ((eventID == (int)HG_ScannerStatus::SIZE_ERROR) || (eventID == (int)HG_ScannerStatus::PAPER_HOLE))
|
||
{
|
||
m_hgScanner->StopScan(0);
|
||
}
|
||
|
||
};
|
||
ScannerGlue glue = {imageready, deviceevent};
|
||
m_hgScanner.reset(new Scanner(glue));
|
||
}
|
||
|
||
UsbScanner::~UsbScanner()
|
||
{
|
||
if (!m_images.IsShutDown())
|
||
m_images.ShutDown();
|
||
|
||
if (!m_scannerEvents.IsShutDown())
|
||
m_scannerEvents.ShutDown();
|
||
|
||
if (m_hgScanner.get())
|
||
m_hgScanner.reset();
|
||
|
||
if(m_usb.get())
|
||
m_usb.reset();
|
||
}
|
||
|
||
void UsbScanner::StartScan(int scancount)
|
||
{
|
||
ClearImages();
|
||
ClearErrorEvents();
|
||
m_hgScanner->SetDstScanNum(scancount <= 0 ? 1 : scancount);
|
||
m_hgScanner->put(S_EVT_START_SCAN);
|
||
}
|
||
|
||
void UsbScanner::StopScan()
|
||
{
|
||
m_hgScanner->put(S_EVT_STOP_SCAN);
|
||
}
|
||
|
||
void UsbScanner::ConfigScanParam(HG_ScanConfiguration config)
|
||
{
|
||
m_startscan = true;
|
||
imageremain = 0;
|
||
eventsramain = 0;
|
||
m_hgScanner->ConfigScanParam(config);
|
||
}
|
||
|
||
bool UsbScanner::FeederLoaded()
|
||
{
|
||
return m_hgScanner->isFeederLoaded();
|
||
}
|
||
std::string UsbScanner::GetSerial()
|
||
{
|
||
auto info = GetScanInfoFromJson();
|
||
return info.SerialNum;
|
||
}
|
||
|
||
void UsbScanner::SetSerial(std::string serial)
|
||
{
|
||
if (m_serial.length() != 14)
|
||
{
|
||
LOG("SetSerial error length,length must be 14 \n");
|
||
return;
|
||
}
|
||
m_serial = serial;
|
||
}
|
||
|
||
std::string UsbScanner::GetFWVersion()
|
||
{
|
||
LOG(" GetFWVersion----------------- \n");
|
||
// JsonConfig js;
|
||
auto info = js_config.GetScanInfo();
|
||
return mapFradme_SP[info.SpeedMode].FWVERSIO;
|
||
}
|
||
|
||
void UsbScanner::SetFwVersion(std::string fwversion)
|
||
{
|
||
if (fwversion.length() != 10)
|
||
{
|
||
LOG("SetFwVersion error length \n");
|
||
return;
|
||
}
|
||
m_fwversion = fwversion;
|
||
}
|
||
|
||
int UsbScanner::GetRollerNum()
|
||
{
|
||
return 1;
|
||
}
|
||
|
||
void UsbScanner::ClearRollerNum()
|
||
{
|
||
}
|
||
|
||
void UsbScanner::InitScanner()
|
||
{
|
||
}
|
||
|
||
void UsbScanner::ClearImages()
|
||
{
|
||
while (m_images.Size() > 0)
|
||
{
|
||
auto jpeg = m_images.Take();
|
||
// tjFree(jpeg.pJpegData);
|
||
}
|
||
imageremain = 0;
|
||
}
|
||
|
||
static int aquiredimgindex = 0;
|
||
HG_JpegCompressInfo UsbScanner::GetImage()
|
||
{
|
||
HG_JpegCompressInfo ret = {0};
|
||
if (m_images.Size() > 0 && !m_images.IsShutDown())
|
||
{
|
||
m_hgScanner->list_image_num(m_images.Size());
|
||
ret = m_images.Take();
|
||
imageremain--;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
HG_Msg UsbScanner::GetEvent()
|
||
{
|
||
HG_Msg ret = {(int)HG_ScannerStatus::NORMAL, ""};
|
||
if (m_scannerEvents.Size() > 0 && !m_scannerEvents.IsShutDown())
|
||
{
|
||
ret = m_scannerEvents.Take();
|
||
eventsramain--;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
void UsbScanner::ClearErrorEvents()
|
||
{
|
||
while (m_scannerEvents.Size() > 0)
|
||
{
|
||
m_scannerEvents.Take();
|
||
}
|
||
eventsramain = 0;
|
||
}
|
||
|
||
void UsbScanner::ClearHWError()
|
||
{
|
||
m_hgScanner->put(S_EVT_CLEAR_ERR);
|
||
LOG("Put Event S_EVT_CLEAR_ERR\n");
|
||
}
|
||
|
||
bool UsbScanner::GetImagequeueEmpty()
|
||
{
|
||
if (m_images.Size() != 0)
|
||
{
|
||
printf("队列剩余图像帧数:%d\r\n",m_images.Size());
|
||
}
|
||
return m_images.Size() == 0;
|
||
}
|
||
|
||
bool UsbScanner::GetEventQueueEmpty()
|
||
{
|
||
return eventsramain == 0;
|
||
}
|
||
|
||
void UsbScanner::close_v4l2()
|
||
{
|
||
m_hgScanner->close_v4l2();
|
||
}
|
||
HG_JpegCompressInfo UsbScanner::GetFrontImage()
|
||
{
|
||
HG_JpegCompressInfo ret = {0};
|
||
if (m_images.Size() > 0)
|
||
ret = m_images.Front();
|
||
return ret;
|
||
}
|
||
|
||
HG_Msg UsbScanner::GetEventFront()
|
||
{
|
||
HG_Msg ret = {(int)HG_ScannerStatus::NORMAL, ""};
|
||
if (m_scannerEvents.Size() > 0 && !m_scannerEvents.IsShutDown())
|
||
{
|
||
ret = m_scannerEvents.Front();
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
void UsbScanner::CreatCorrectData(int correctmode)
|
||
{
|
||
ClearErrorEvents();
|
||
m_hgScanner->CreatCorrectData(correctmode);
|
||
}
|
||
|
||
bool UsbScanner::IsScanning()
|
||
{
|
||
return m_hgScanner->IsScanning();
|
||
}
|
||
|
||
void UsbScanner::SetFlatParam(int type, int *value)
|
||
{
|
||
std::string ttype;
|
||
switch ((USBCommand)type)
|
||
{
|
||
case USBCommand::SEND_COLOR_FLAT:
|
||
ttype = "color";
|
||
break;
|
||
case USBCommand::SEND_COLORCORRECT_FLAT:
|
||
ttype = "correctColor";
|
||
break;
|
||
case USBCommand::SEND_GRAY_FLAT:
|
||
ttype = "gray";
|
||
break;
|
||
case USBCommand::SEND_GRAYCORRECT_FLAT:
|
||
ttype = "correctGray";
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
CaptureParams UsbScanner::GetCaptureParams()
|
||
{
|
||
return m_hgScanner->GetCaptureParams();
|
||
}
|
||
void UsbScanner::UpdateScanInfo(int type, void *data)
|
||
{
|
||
auto info = GetScanInfoFromJson();
|
||
switch ((USBCommand)type)
|
||
{
|
||
case USBCommand::SEND_SERIAL:
|
||
{
|
||
char serial[15];
|
||
serial[14] = '\0';
|
||
memcpy(serial, data, 14);
|
||
std::string serial_s(serial);
|
||
m_hgScanner->GetScanInfo().SerialNum = serial_s;
|
||
info.SerialNum = serial_s;
|
||
SaveScaninfo(info);
|
||
}
|
||
|
||
break;
|
||
case USBCommand::SET_JUST_COF_H:
|
||
info.HRatio = *(unsigned int *)(data);
|
||
break;
|
||
case USBCommand::SET_JUST_COF_V:
|
||
info.VRatio = *(unsigned int *)(data);
|
||
printf("SET_JUST_COF_V = %d %f\n", info.VRatio, *(float *)(data));
|
||
break;
|
||
case USBCommand::CLR_ROLLER_NUM:
|
||
info.RollerNum = 0;
|
||
break;
|
||
case USBCommand::CLR_SCAN_NUM:
|
||
info.TotalScanned = 0;
|
||
break;
|
||
case USBCommand::SET_SLEEP_TIME:
|
||
info.SleepTime = *(unsigned int *)(data);
|
||
printf("set sleep time = %d \n", info.SleepTime);
|
||
SaveScaninfo(info);
|
||
//stop_countdown();
|
||
start_enter_lowpwoer();
|
||
return;
|
||
case USBCommand::SET_SPEED_MODE:
|
||
if (*(unsigned int *)(data) > SPEED_MODE_MAX)
|
||
info.SpeedMode = 3;
|
||
else
|
||
info.SpeedMode = *(unsigned int *)(data);
|
||
|
||
LOG("UsbScanner SET SpeedMode == %d------ \n", info.SpeedMode);
|
||
|
||
iter = mapFradme_SP.find(info.SpeedMode);
|
||
if (iter != mapFradme_SP.end())
|
||
info.FWVersion = iter->second.FWVERSIO;
|
||
|
||
SaveScaninfo(info);
|
||
m_hgScanner->updateSpeedMode();
|
||
LOG("UsbScanner SET SpeedMode == %d-------info.FWVersion = %s \n", info.SpeedMode, info.FWVersion.c_str());
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
SaveScaninfo(info);
|
||
m_hgScanner->UpdateScanInfo();
|
||
}
|
||
|
||
ScannerScanInfo UsbScanner::GetScanInfo()
|
||
{
|
||
return m_hgScanner->GetScanInfo();
|
||
}
|
||
|
||
void UsbScanner::SetLEDStatus(LedStatus status)
|
||
{
|
||
m_hgScanner->getPanelLeds().setStatus(status);
|
||
}
|
||
|
||
std::string UsbScanner::GetSysInfo()
|
||
{
|
||
return m_hgScanner->GetSysInfo();
|
||
}
|
||
|
||
int UsbScanner::read_bulk(void *pdata, int length ,int time)
|
||
{
|
||
int ret=0;
|
||
|
||
if(pdata==nullptr || length == 0)
|
||
return ret;
|
||
|
||
if(m_usb.get()&& m_usb->is_connected())
|
||
{
|
||
ret = m_usb->read_bulk(pdata,length,time);
|
||
}
|
||
return ret;
|
||
}
|
||
int UsbScanner::write_bulk(void *pdata, int length)
|
||
{
|
||
int ret=0;
|
||
|
||
if(pdata==nullptr || length == 0)
|
||
return ret;
|
||
|
||
if(m_usb.get()&& m_usb->is_connected())
|
||
{
|
||
ret = m_usb->write_bulk(pdata,length);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
bool UsbScanner::is_connect()
|
||
{
|
||
if(!m_usb.get())
|
||
return false;
|
||
return m_usb->is_connected();
|
||
}
|
||
|
||
|
||
void UsbScanner::mount_usb_device()
|
||
{
|
||
|
||
if ((access("/dev/ffs-camtp/ep0", F_OK)) != -1)
|
||
{
|
||
printf("exit mount_usb_device !!!\r\n");
|
||
return;
|
||
}
|
||
|
||
char p[12];
|
||
sprintf(p,"%0x",pid_);
|
||
char v[12];
|
||
sprintf(v,"%0x",vid_);
|
||
std::string pid = p;
|
||
std::string vid = v;
|
||
|
||
std::string str = "modprobe libcomposite\n \
|
||
mkdir /var/cfg\n \
|
||
mount none /var/cfg -t configfs\n \
|
||
mkdir /var/cfg/usb_gadget/g1\n \
|
||
cd /var/cfg/usb_gadget/g1\n \
|
||
mkdir configs/c.1 \n \
|
||
mkdir functions/ffs.camtp\n \
|
||
mkdir strings/0x409\n \
|
||
mkdir configs/c.1/strings/0x409\n \
|
||
echo 0x0306 > idProduct\n \
|
||
echo 0x3072 > idVendor\n \
|
||
echo \"01234567AABBCCDDEE\" > strings/0x409/serialnumber\n \
|
||
echo \"Holdtecs Technologies\" > strings/0x409/manufacturer\n \
|
||
echo \"The Holdtecs Product !\" > strings/0x409/product\n \
|
||
echo \"Conf 1\" > configs/c.1/strings/0x409/configuration\n \
|
||
echo 120 > configs/c.1/MaxPower\n \
|
||
ln -s functions/ffs.camtp configs/c.1\n \
|
||
mkdir /dev/ffs-camtp\n \
|
||
mount -t functionfs camtp /dev/ffs-camtp";
|
||
int result = system(str.c_str());
|
||
} |