添加硬件(FPGA)代码;工作状态是否记录进日志通过wValue!=0来判断
This commit is contained in:
parent
f9217b32c5
commit
d878284efb
|
@ -0,0 +1,360 @@
|
|||
//
|
||||
// Created by Nick on 2019/4/7.
|
||||
//
|
||||
#include "FpgaComm.h"
|
||||
|
||||
#include <thread>
|
||||
#include "../uart/uartregsaccess.h"
|
||||
#include <iostream>
|
||||
|
||||
#define Reg(x) (fpgaParams.x)
|
||||
#define RegIndex(x) (std::distance((unsigned int*)&fpgaParams, (unsigned int*)&fpgaParams.x))
|
||||
#define ReadReg(x) read(RegIndex(x), *((unsigned int*)&fpgaParams.x))
|
||||
#define WriteReg(x) write(RegIndex(x), *((unsigned int*)&fpgaParams.x))
|
||||
#define WR_Reg(x) (WriteReg(x),ReadReg(x))
|
||||
|
||||
#define CO(x) std::cout << #x << " : "<< RegIndex(x) << std::endl
|
||||
|
||||
FpgaComm::FpgaComm(int bauds) : bauds_(bauds)
|
||||
{
|
||||
m_regsAccess.reset(new UartRegsAccess(FPGA_UART, bauds_, 0x03, 0x83));
|
||||
update();
|
||||
|
||||
Reg(AledR).sample = 256;
|
||||
WR_Reg(AledR);
|
||||
}
|
||||
|
||||
bool FpgaComm::read(unsigned int addr, unsigned int& val) {
|
||||
return m_regsAccess->read(addr, val);
|
||||
}
|
||||
|
||||
bool FpgaComm::write(unsigned int addr, unsigned int val) {
|
||||
return m_regsAccess->write(addr, val);
|
||||
}
|
||||
|
||||
void FpgaComm::regsAccess_reset(bool enable){
|
||||
if(enable)
|
||||
{
|
||||
if(!m_regsAccess.get())
|
||||
m_regsAccess.reset(new UartRegsAccess(FPGA_UART, bauds_, 0x03, 0x83));
|
||||
update();
|
||||
return;
|
||||
}
|
||||
if(m_regsAccess.get())
|
||||
m_regsAccess.reset();
|
||||
}
|
||||
|
||||
void FpgaComm::setFrameHeight(int height){
|
||||
Reg(frame).height = height;
|
||||
WR_Reg(frame);
|
||||
}
|
||||
|
||||
int FpgaComm::getFrameHeight()
|
||||
{
|
||||
return Reg(frame).height;
|
||||
}
|
||||
|
||||
void FpgaComm::setFrameNum(int num){
|
||||
Reg(frame).num = num;
|
||||
WR_Reg(frame);
|
||||
}
|
||||
|
||||
void FpgaComm::enableLed(bool bEnable) {
|
||||
Reg(AledR).ledEnable = bEnable;
|
||||
WR_Reg(AledR);
|
||||
#ifdef HAS_UV
|
||||
Reg(BledR).ledEnable = bEnable;
|
||||
WR_Reg(BledR);
|
||||
#else
|
||||
Reg(BledR).ledEnable = bEnable;
|
||||
WR_Reg(BledR);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FpgaComm::enableUV(bool enable){
|
||||
#ifdef HAS_UV
|
||||
isUVEnable = enable;
|
||||
Reg(BledR).ledEnable = isUVEnable;
|
||||
WR_Reg(BledR);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FpgaComm::capture() {
|
||||
Reg(cmd).cmd = 0;
|
||||
WriteReg(cmd);
|
||||
Reg(cmd).cmd = 1;
|
||||
WriteReg(cmd);
|
||||
}
|
||||
|
||||
int FpgaComm::getRegs(int addr) {
|
||||
return fpgaParams.regs[addr];
|
||||
}
|
||||
|
||||
void FpgaComm::setRegs(int addr, int value) {
|
||||
fpgaParams.regs[addr] = value;
|
||||
write(addr, value);
|
||||
read(addr, fpgaParams.regs[addr]);
|
||||
}
|
||||
|
||||
void FpgaComm::setAGain(int indexGain, int value) {
|
||||
int index = indexGain;
|
||||
int val;// = value
|
||||
value>=511?val=511:val=value;
|
||||
index++;
|
||||
fpgaParams.Aad.ad0_addr = index*2;
|
||||
fpgaParams.Aad.ad1_addr = fpgaParams.Aad.ad0_addr + 1;
|
||||
fpgaParams.Aad.ad0_value = val;
|
||||
fpgaParams.Aad.ad1_value = val>255?1:0;
|
||||
fpgaParams.Aad.ad0_rw = 0;
|
||||
fpgaParams.Aad.ad1_rw = 0;
|
||||
write(0x04,*(int*)&fpgaParams.Aad);
|
||||
Reg(mode).adcA = 1;
|
||||
WriteReg(mode);
|
||||
Reg(mode).adcA = 0;
|
||||
WriteReg(mode);
|
||||
}
|
||||
|
||||
void FpgaComm::setBGain(int indexGain, int value) {
|
||||
int index = indexGain;
|
||||
int val;// = value
|
||||
value>=511?val=511:val=value;
|
||||
index++;
|
||||
fpgaParams.Bad.ad0_addr = index*2;
|
||||
fpgaParams.Bad.ad1_addr = index*2 + 1;
|
||||
fpgaParams.Bad.ad0_value = val;
|
||||
fpgaParams.Bad.ad1_value = val>255?1:0;
|
||||
fpgaParams.Bad.ad0_rw = 0;
|
||||
fpgaParams.Bad.ad1_rw = 0;
|
||||
write(0x07,*(int*)&fpgaParams.Bad);
|
||||
Reg(mode).adcB = 1;
|
||||
WriteReg(mode);
|
||||
Reg(mode).adcB = 0;
|
||||
WriteReg(mode);
|
||||
}
|
||||
|
||||
void FpgaComm::setAOffset(int indexOffset, int value) {
|
||||
Reg(Aad).ad0_rw = 0;
|
||||
Reg(Aad).ad1_rw = 0;
|
||||
Reg(Aad).ad0_addr = indexOffset + 0x0e;
|
||||
Reg(Aad).ad1_addr = 0x14;
|
||||
Reg(Aad).ad0_value = value;
|
||||
WriteReg(Aad);
|
||||
Reg(mode).adcA = 1;
|
||||
WriteReg(mode);
|
||||
Reg(mode).adcA = 0;
|
||||
WriteReg(mode);
|
||||
}
|
||||
|
||||
void FpgaComm::setBOffset(int indexOffset, int value) {
|
||||
Reg(Bad).ad0_rw = 0;
|
||||
Reg(Bad).ad1_rw = 0;
|
||||
Reg(Bad).ad0_addr = indexOffset + 0x0e;
|
||||
Reg(Bad).ad1_addr = 0x14;
|
||||
Reg(Bad).ad0_value = value;
|
||||
WriteReg(Bad);
|
||||
Reg(mode).adcB = 1;
|
||||
WriteReg(mode);
|
||||
Reg(mode).adcB = 0;
|
||||
WriteReg(mode);
|
||||
}
|
||||
|
||||
void FpgaComm::setAExposureR(int value) {
|
||||
Reg(AledR).ledR = value;
|
||||
WR_Reg(AledR);
|
||||
}
|
||||
|
||||
void FpgaComm::setAExposureG(int value) {
|
||||
Reg(AledGB).ledG = value;
|
||||
WR_Reg(AledGB);
|
||||
}
|
||||
|
||||
void FpgaComm::setAExposureB(int value) {
|
||||
Reg(AledGB).ledB = value;
|
||||
WR_Reg(AledGB);
|
||||
}
|
||||
|
||||
void FpgaComm::setAExposureUV(int value){
|
||||
#ifdef HAS_UV
|
||||
Reg(UVLed).ledASide = value;
|
||||
WR_Reg(UVLed);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FpgaComm::setBExposureR(int value) {
|
||||
Reg(BledR).ledR = value;
|
||||
WR_Reg(BledR);
|
||||
}
|
||||
|
||||
void FpgaComm::setBExposureG(int value) {
|
||||
Reg(BledGB).ledG = value;
|
||||
WR_Reg(BledGB);
|
||||
}
|
||||
|
||||
void FpgaComm::setBExposureB(int value) {
|
||||
Reg(BledGB).ledB = value;
|
||||
WR_Reg(BledGB);
|
||||
}
|
||||
|
||||
void FpgaComm::setBExpousreUV(int value){
|
||||
#ifdef HAS_UV
|
||||
Reg(UVLed).ledBSide = value;
|
||||
WR_Reg(UVLed);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FpgaComm::setSp(int value)
|
||||
{
|
||||
Reg(mode).sp = value;
|
||||
WR_Reg(mode);
|
||||
}
|
||||
|
||||
int FpgaComm::getSp()
|
||||
{
|
||||
return Reg(mode).sp;
|
||||
}
|
||||
|
||||
void FpgaComm::setColorMode(int mode)
|
||||
{
|
||||
Reg(mode).colorMode = mode;
|
||||
WR_Reg(mode);
|
||||
}
|
||||
|
||||
int FpgaComm::getColorMode()
|
||||
{
|
||||
return Reg(mode).colorMode;
|
||||
}
|
||||
|
||||
void FpgaComm::setSample(int sample)
|
||||
{
|
||||
Reg(mode).sample = sample;
|
||||
WR_Reg(mode);
|
||||
Reg(AledR).sample = sample;
|
||||
WR_Reg(AledR);
|
||||
}
|
||||
|
||||
void FpgaComm::EnableTest(bool bTest)
|
||||
{
|
||||
Reg(mode).selftest = bTest;
|
||||
WR_Reg(mode);
|
||||
}
|
||||
|
||||
int FpgaComm::IsTest()
|
||||
{
|
||||
return Reg(mode).selftest;
|
||||
}
|
||||
|
||||
int FpgaComm::getSample()
|
||||
{
|
||||
return Reg(mode).sample;
|
||||
}
|
||||
|
||||
void FpgaComm::setDpi(int dpi)
|
||||
{
|
||||
Reg(mode).dpi = dpi;
|
||||
WR_Reg(mode);
|
||||
}
|
||||
|
||||
int FpgaComm::getDpi()
|
||||
{
|
||||
return Reg(mode).dpi;
|
||||
}
|
||||
|
||||
//20190626 YHP autoTrig function
|
||||
void FpgaComm::setTrigMode(bool isArmMode) {
|
||||
unsigned int tmp;
|
||||
read(0x0b, tmp);
|
||||
if(!isArmMode){ //default value+ ARM MODE,bit27 =0;
|
||||
fpgaParams.TrigMode = tmp & 0XFBFFFFFF;
|
||||
}else{
|
||||
fpgaParams.TrigMode = tmp |(1<<26);
|
||||
}
|
||||
WR_Reg(TrigMode);
|
||||
}
|
||||
void FpgaComm::setDelayTime(int value) {
|
||||
Reg(DelayTime) = value;
|
||||
WR_Reg(DelayTime);
|
||||
}
|
||||
|
||||
void FpgaComm::update()
|
||||
{
|
||||
for(int i = 0; i < MAX_REGS; i++)
|
||||
{
|
||||
read(i, fpgaParams.regs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void FpgaComm::enableJamCheck(bool b){
|
||||
//Reg(BledR).user_define.led_sample.jamEnable = b;
|
||||
//WR_Regs(0x08);
|
||||
}
|
||||
|
||||
void FpgaComm::resetADC() {
|
||||
|
||||
fpgaParams.Aad.ad0_rw = 0;
|
||||
fpgaParams.Aad.ad0_addr = 0;
|
||||
fpgaParams.Aad.ad0_value = 0;
|
||||
fpgaParams.Aad.ad1_rw = 0;
|
||||
fpgaParams.Aad.ad1_addr = 0;
|
||||
fpgaParams.Aad.ad1_value = 0;
|
||||
WR_Reg(Aad);
|
||||
fpgaParams.mode.adcA = 1;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.mode.adcA = 0;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.Bad.ad0_rw = 0;
|
||||
fpgaParams.Bad.ad0_addr = 0;
|
||||
fpgaParams.Bad.ad0_value = 0;
|
||||
fpgaParams.Bad.ad1_rw = 0;
|
||||
fpgaParams.Bad.ad1_addr = 0;
|
||||
fpgaParams.Bad.ad1_value = 0;
|
||||
WR_Reg(Bad);
|
||||
fpgaParams.mode.adcB = 1;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.mode.adcB = 0;
|
||||
WR_Reg(mode);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
fpgaParams.Aad.ad0_rw = 0;
|
||||
fpgaParams.Aad.ad0_addr = 0;
|
||||
fpgaParams.Aad.ad0_value = 7;
|
||||
fpgaParams.Aad.ad1_rw = 0;
|
||||
fpgaParams.Aad.ad1_addr = 0;
|
||||
fpgaParams.Aad.ad1_value = 7;
|
||||
WR_Reg(Aad);
|
||||
fpgaParams.mode.adcA = 1;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.mode.adcA = 0;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.Bad.ad0_rw = 0;
|
||||
fpgaParams.Bad.ad0_addr = 0;
|
||||
fpgaParams.Bad.ad0_value = 7;
|
||||
fpgaParams.Bad.ad1_rw = 0;
|
||||
fpgaParams.Bad.ad1_addr = 0;
|
||||
fpgaParams.Bad.ad1_value = 7;
|
||||
WR_Reg(Bad);
|
||||
fpgaParams.mode.adcB = 1;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.mode.adcB = 0;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.Aad.ad0_rw = 0;
|
||||
fpgaParams.Aad.ad0_addr = 1;
|
||||
fpgaParams.Aad.ad0_value = 0x50;
|
||||
fpgaParams.Aad.ad1_rw = 0;
|
||||
fpgaParams.Aad.ad1_addr = 1;
|
||||
fpgaParams.Aad.ad1_value = 0x50;
|
||||
WR_Reg(Aad);
|
||||
fpgaParams.mode.adcA = 1;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.mode.adcA = 0;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.Bad.ad0_rw = 0;
|
||||
fpgaParams.Bad.ad0_addr = 1;
|
||||
fpgaParams.Bad.ad0_value = 0x50;
|
||||
fpgaParams.Bad.ad1_rw = 0;
|
||||
fpgaParams.Bad.ad1_addr = 1;
|
||||
fpgaParams.Bad.ad1_value = 0x50;
|
||||
WR_Reg(Bad);
|
||||
fpgaParams.mode.adcB = 1;
|
||||
WR_Reg(mode);
|
||||
fpgaParams.mode.adcB = 0;
|
||||
WR_Reg(mode);
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "../uart/regsaccess.h"
|
||||
|
||||
#ifdef HAS_UV
|
||||
#define MAX_REGS 0x0e
|
||||
#else
|
||||
#define MAX_REGS 0x0d
|
||||
#endif
|
||||
|
||||
typedef struct Frame_FPGA
|
||||
{
|
||||
unsigned short int height;
|
||||
unsigned short int num : 8;
|
||||
unsigned short int reserved : 8;
|
||||
|
||||
} FrameFpga;
|
||||
|
||||
typedef struct Mode_FPGA
|
||||
{
|
||||
unsigned short int colorMode : 1;
|
||||
unsigned short int dpi : 2;
|
||||
unsigned short int led : 1;
|
||||
unsigned short sample : 9;
|
||||
unsigned short int adcA : 1;
|
||||
unsigned short int adcB : 1;
|
||||
unsigned short int selftest : 1;
|
||||
unsigned short int sp;
|
||||
} ModeFpga;
|
||||
|
||||
typedef struct CMD_FPGA
|
||||
{
|
||||
unsigned int cmd : 1; //start : 1 , stop : 0
|
||||
unsigned int reserved : 31;
|
||||
} CmdFpga;
|
||||
|
||||
typedef struct STATUS_FPGA
|
||||
{
|
||||
unsigned int status : 1; //start : 1 , stop : 0
|
||||
unsigned int reserved : 31;
|
||||
} StatusFpga;
|
||||
|
||||
typedef struct Ad_Gain
|
||||
{
|
||||
unsigned short int gain_low8 : 8;
|
||||
unsigned short int gain_hight : 1;
|
||||
unsigned int reserved : 23;
|
||||
} AdGain;
|
||||
|
||||
|
||||
typedef struct CIS_AD_Gain
|
||||
{
|
||||
unsigned short int ad0_value : 8; //!< 数据位
|
||||
unsigned short int ad0_reserved : 2; //!< 保留位
|
||||
unsigned short int ad0_addr : 5; //!< 寄存器地址
|
||||
unsigned short int ad0_rw : 1; //!< 读写位 1:读, 0:写
|
||||
unsigned short int ad1_value : 8; //!< 数据位
|
||||
unsigned short int ad1_reserved : 2; //!< 保留位
|
||||
unsigned short int ad1_addr : 5; //!< 寄存器地址
|
||||
unsigned short int ad1_rw : 1; //!< 读写位 1:读, 0:写;
|
||||
} CisAdGain;
|
||||
|
||||
typedef struct CIS_LED_RF
|
||||
{
|
||||
unsigned short int ledEnable : 1;
|
||||
unsigned short int fanMode : 2;
|
||||
unsigned short int jamEnable : 1;
|
||||
unsigned short int sample : 9;
|
||||
unsigned short int reserved : 3;
|
||||
unsigned short int ledR;
|
||||
} CisLedRF;
|
||||
|
||||
typedef struct CIS_LED_R
|
||||
{
|
||||
unsigned short int ledEnable : 1;
|
||||
unsigned short int sample : 9;
|
||||
unsigned short int reserved : 6;
|
||||
unsigned short int ledR;
|
||||
} CisLedR;
|
||||
|
||||
typedef struct CIS_LED_GB
|
||||
{
|
||||
unsigned short int ledG;
|
||||
unsigned short int ledB;
|
||||
} CisLedGB;
|
||||
|
||||
typedef struct CIS_LED_UV
|
||||
{
|
||||
unsigned short int ledASide;
|
||||
unsigned short int ledBSide;
|
||||
} CisLedUv;
|
||||
|
||||
typedef union Fpga_Params
|
||||
{
|
||||
struct
|
||||
{
|
||||
FrameFpga frame; //0x00
|
||||
ModeFpga mode; //0x01
|
||||
CmdFpga cmd; //0x02
|
||||
StatusFpga status; //0x03
|
||||
CisAdGain Aad; //0x04
|
||||
CisLedR AledR; //0x05
|
||||
CisLedGB AledGB; //0x06
|
||||
CisAdGain Bad; //0x07
|
||||
#ifndef G300
|
||||
CisLedRF BledR; //0x08
|
||||
#else
|
||||
CisLedR BledR; //0x08
|
||||
#endif
|
||||
CisLedGB BledGB; //0x09
|
||||
unsigned int ExpIncr; //0x0a
|
||||
unsigned int TrigMode; //0x0b
|
||||
unsigned int DelayTime; //0x0c
|
||||
CisLedUv UVLed;
|
||||
};
|
||||
unsigned int regs[14];
|
||||
} FpgaParams;
|
||||
|
||||
#define FPGA_UART "/dev/ttyUSB0"
|
||||
#define MOTOR_UART "/dev/ttyS4"
|
||||
|
||||
enum
|
||||
{
|
||||
GRAY_MODE = 0,
|
||||
COLOR_MODE,
|
||||
};
|
||||
enum
|
||||
{
|
||||
DPI_300 = 0,
|
||||
DPI_200,
|
||||
};
|
||||
enum
|
||||
{
|
||||
CIS_GAIN_IND_COUNT = 6,
|
||||
};
|
||||
enum
|
||||
{
|
||||
CIS_OFFSET_IND_COUNT = 6,
|
||||
};
|
||||
|
||||
class FpgaComm : public IRegsAccess
|
||||
{
|
||||
int bauds_ = 921600;
|
||||
|
||||
public:
|
||||
FpgaComm(int bauds = 921600);
|
||||
virtual ~FpgaComm(){}
|
||||
|
||||
void reset();
|
||||
void regsAccess_reset(bool enable);
|
||||
void setRegs(int addr, int value);
|
||||
int getRegs(int addr);
|
||||
void setFrameHeight(int height);
|
||||
int getFrameHeight();
|
||||
void setFrameNum(int num);
|
||||
void enableLed(bool bEnable);
|
||||
void enableUV(bool enable);
|
||||
void capture();
|
||||
void setAGain(int indexGain, int value);
|
||||
void setBGain(int indexGain, int value);
|
||||
void setAOffset(int indexOffset, int value);
|
||||
void setBOffset(int indexOffset, int value);
|
||||
|
||||
void setAExposureR(int value);
|
||||
void setAExposureG(int value);
|
||||
void setAExposureB(int value);
|
||||
void setAExposureUV(int value);
|
||||
|
||||
void setBExposureR(int value);
|
||||
void setBExposureG(int value);
|
||||
void setBExposureB(int value);
|
||||
void setBExpousreUV(int value);
|
||||
|
||||
void setSp(int value);
|
||||
int getSp();
|
||||
|
||||
void EnableTest(bool bTest);
|
||||
int IsTest();
|
||||
|
||||
void setColorMode(int mode);
|
||||
int getColorMode();
|
||||
|
||||
void setDpi(int dpi);
|
||||
int getDpi();
|
||||
|
||||
void setSample(int sample);
|
||||
int getSample();
|
||||
|
||||
//20190626 YHP autoTrig function
|
||||
void setDelayTime(int value);
|
||||
void setTrigMode(bool isArmMode);
|
||||
|
||||
void update();
|
||||
void enableJamCheck(bool b);
|
||||
void resetADC();
|
||||
virtual bool write(unsigned int addr, unsigned int val);
|
||||
virtual bool read(unsigned int addr, unsigned int& val);
|
||||
|
||||
private:
|
||||
FpgaParams fpgaParams;
|
||||
std::shared_ptr<IRegsAccess> m_regsAccess;
|
||||
};
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,326 @@
|
|||
// hardware drivers
|
||||
//
|
||||
// Contains: CIS, MotorBoard, ...
|
||||
//
|
||||
// Date: 2023-12-18
|
||||
|
||||
#include <sane_opt_json/base_opt.h>
|
||||
#include <functional>
|
||||
#include <base/packet.h>
|
||||
#include <base/data.h>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
// image handler callback proto
|
||||
//
|
||||
// dyn_mem_ptr: image data buffer, or be uint32_t if bool was false
|
||||
//
|
||||
// bool: true - image, dyn_mem_ptr is image data buffer; false - dyn_mem_ptr is an uint32_t code of hardware event
|
||||
//
|
||||
// LPPACKIMAGE: image information, ignored when bool is false
|
||||
#define IMAGE_HANDLER_PROTO void(dyn_mem_ptr, bool, LPPACKIMAGE)
|
||||
|
||||
class FpgaComm;
|
||||
|
||||
class scanner_hw : public sane_opt_provider
|
||||
{
|
||||
std::function<IMAGE_HANDLER_PROTO> img_handler_;
|
||||
bool scanning_ = false;
|
||||
bool auto_scan_ = false;
|
||||
std::unique_ptr<FpgaComm> img_controller_;
|
||||
|
||||
enum
|
||||
{
|
||||
SIDE_FRONT = 0,
|
||||
SIDE_BACK,
|
||||
SIDE_COUNT,
|
||||
};
|
||||
enum
|
||||
{
|
||||
COLOR_IND_BLUE = 0,
|
||||
COLOR_IND_GREEN,
|
||||
COLOR_IND_RED,
|
||||
COLOR_IND_COUNT,
|
||||
};
|
||||
std::string mode_;
|
||||
int dpi_ = 300;
|
||||
int baud_ = 921600;
|
||||
int delay_ = 1000;
|
||||
int frame_h_ = 12;
|
||||
int sample_ = 256;
|
||||
int exposure_[SIDE_COUNT][COLOR_IND_COUNT];
|
||||
int gain_[SIDE_COUNT];
|
||||
int off_[SIDE_COUNT];
|
||||
std::map<std::string, std::function<void(void*)>> opt_handler_;
|
||||
|
||||
|
||||
void init(void);
|
||||
|
||||
public:
|
||||
scanner_hw();
|
||||
protected:
|
||||
~scanner_hw();
|
||||
|
||||
// sane_opt_provider
|
||||
public:
|
||||
// return malloc(), real data size stored in parameter 'size'. invoker should free() the returned value
|
||||
virtual char* get_value(const char* name, void* value, size_t* size, int* err = nullptr) override;
|
||||
virtual int set_value(const char* name, void* val) override;
|
||||
|
||||
// operation ...
|
||||
public:
|
||||
int open(std::function<IMAGE_HANDLER_PROTO> image_handler);
|
||||
int start_scan(void);
|
||||
int stop_scan(void);
|
||||
int close(void);
|
||||
};
|
||||
// {
|
||||
// "mode": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "颜色模式",
|
||||
// "desc": "选择色彩模式",
|
||||
// "type": "string",
|
||||
// "fix-id": 34819,
|
||||
// "ui-pos": 10,
|
||||
// "auth": 0,
|
||||
// "size": 12,
|
||||
// "cur": "彩色",
|
||||
// "default": "彩色",
|
||||
// "range": ["彩色", "灰度"]
|
||||
// },
|
||||
// "resolution": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "分辨率",
|
||||
// "desc": "设置扫描图像的分辨率",
|
||||
// "type": "int",
|
||||
// "fix-id": 34840,
|
||||
// "ui-pos": 11,
|
||||
// "auth": 0,
|
||||
// "size": 4,
|
||||
// "cur": 300,
|
||||
// "default": 300,
|
||||
// "range": [200, 300]
|
||||
// },
|
||||
// "baud": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "波特率",
|
||||
// "desc": "CIS控制通信速率",
|
||||
// "type": "int",
|
||||
// "ui-pos": 12,
|
||||
// "auth": 0,
|
||||
// "size": 4,
|
||||
// "cur": 921600,
|
||||
// "default": 921600,
|
||||
// "range": [110, 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 500000, 921600, 1500000]
|
||||
// },
|
||||
// "act-after": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "延迟响应",
|
||||
// "desc": "采集头接受命令后的动作延迟时间",
|
||||
// "type": "int",
|
||||
// "ui-pos": 12,
|
||||
// "auth": 0,
|
||||
// "unit": "microsec",
|
||||
// "size": 4,
|
||||
// "cur": 1000,
|
||||
// "default": 1000
|
||||
// },
|
||||
// "fram-h": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "帧高度",
|
||||
// "desc": "采集头每一帧的采集高度",
|
||||
// "type": "int",
|
||||
// "ui-pos": 13,
|
||||
// "auth": 0,
|
||||
// "size": 4,
|
||||
// "cur": 12,
|
||||
// "default": 12
|
||||
// },
|
||||
// "sample": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "采样频率",
|
||||
// "desc": "采样频率",
|
||||
// "type": "int",
|
||||
// "ui-pos": 14,
|
||||
// "auth": 0,
|
||||
// "size": 4,
|
||||
// "cur": 256,
|
||||
// "default": 256
|
||||
// },
|
||||
// "expo-fb": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "曝光度(正面蓝色通道)",
|
||||
// "desc": "正面蓝色通道的曝光强度",
|
||||
// "type": "int",
|
||||
// "ui-pos": 15,
|
||||
// "auth": 0,
|
||||
// "size": 4,
|
||||
// "cur": 0,
|
||||
// "default": 0,
|
||||
// "range": {
|
||||
// "min": -1000,
|
||||
// "max": 1000,
|
||||
// "step": 1
|
||||
// }
|
||||
// },
|
||||
// "expo-fg": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "曝光度(正面绿色通道)",
|
||||
// "desc": "正面绿色通道的曝光强度",
|
||||
// "type": "int",
|
||||
// "ui-pos": 16,
|
||||
// "auth": 0,
|
||||
// "size": 4,
|
||||
// "cur": 0,
|
||||
// "default": 0,
|
||||
// "range": {
|
||||
// "min": -1000,
|
||||
// "max": 1000,
|
||||
// "step": 1
|
||||
// }
|
||||
// },
|
||||
// "expo-fr": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "曝光度(正面红色通道)",
|
||||
// "desc": "正面红色通道的曝光强度",
|
||||
// "type": "int",
|
||||
// "ui-pos": 17,
|
||||
// "auth": 0,
|
||||
// "size": 4,
|
||||
// "cur": 0,
|
||||
// "default": 0,
|
||||
// "range": {
|
||||
// "min": -1000,
|
||||
// "max": 1000,
|
||||
// "step": 1
|
||||
// }
|
||||
// },
|
||||
// "expo-bb": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "曝光度(背面蓝色通道)",
|
||||
// "desc": "背面蓝色通道的曝光强度",
|
||||
// "type": "int",
|
||||
// "ui-pos": 18,
|
||||
// "auth": 0,
|
||||
// "size": 4,
|
||||
// "cur": 0,
|
||||
// "default": 0,
|
||||
// "range": {
|
||||
// "min": -1000,
|
||||
// "max": 1000,
|
||||
// "step": 1
|
||||
// }
|
||||
// },
|
||||
// "expo-bg": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "曝光度(背面绿色通道)",
|
||||
// "desc": "背面绿色通道的曝光强度",
|
||||
// "type": "int",
|
||||
// "ui-pos": 19,
|
||||
// "auth": 0,
|
||||
// "size": 4,
|
||||
// "cur": 0,
|
||||
// "default": 0,
|
||||
// "range": {
|
||||
// "min": -1000,
|
||||
// "max": 1000,
|
||||
// "step": 1
|
||||
// }
|
||||
// },
|
||||
// "expo-br": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "曝光度(背面红色通道)",
|
||||
// "desc": "背面红色通道的曝光强度",
|
||||
// "type": "int",
|
||||
// "ui-pos": 20,
|
||||
// "auth": 0,
|
||||
// "size": 4,
|
||||
// "cur": 0,
|
||||
// "default": 0,
|
||||
// "range": {
|
||||
// "min": -1000,
|
||||
// "max": 1000,
|
||||
// "step": 1
|
||||
// }
|
||||
// },
|
||||
// "gain-f": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "增益(正面)",
|
||||
// "desc": "正面的增益量",
|
||||
// "type": "int",
|
||||
// "ui-pos": 21,
|
||||
// "auth": 0,
|
||||
// "size": 4,
|
||||
// "cur": 0,
|
||||
// "default": 0,
|
||||
// "range": {
|
||||
// "min": -1000,
|
||||
// "max": 1000,
|
||||
// "step": 1
|
||||
// }
|
||||
// },
|
||||
// "gain-b": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "增益(背面)",
|
||||
// "desc": "背面的增益量",
|
||||
// "type": "int",
|
||||
// "ui-pos": 24,
|
||||
// "auth": 0,
|
||||
// "size": 4,
|
||||
// "cur": 0,
|
||||
// "default": 0,
|
||||
// "range": {
|
||||
// "min": -1000,
|
||||
// "max": 1000,
|
||||
// "step": 1
|
||||
// }
|
||||
// },
|
||||
// "off-f": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "偏移(正面)",
|
||||
// "desc": "正面的偏移量",
|
||||
// "type": "int",
|
||||
// "ui-pos": 27,
|
||||
// "auth": 0,
|
||||
// "size": 4,
|
||||
// "cur": 0,
|
||||
// "default": 0,
|
||||
// "range": {
|
||||
// "min": 0,
|
||||
// "max": 100,
|
||||
// "step": 1
|
||||
// }
|
||||
// },
|
||||
// "off-b": {
|
||||
// "cat": "none",
|
||||
// "group": "CIS",
|
||||
// "title": "偏移(背面)",
|
||||
// "desc": "背面的偏移量",
|
||||
// "type": "int",
|
||||
// "ui-pos": 30,
|
||||
// "auth": 0,
|
||||
// "size": 4,
|
||||
// "cur": 0,
|
||||
// "default": 0,
|
||||
// "range": {
|
||||
// "min": 0,
|
||||
// "max": 100,
|
||||
// "step": 1
|
||||
// }
|
||||
// }
|
||||
// }
|
|
@ -0,0 +1,31 @@
|
|||
#include "DevUtil.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <base/utils.h>
|
||||
|
||||
#define IOEXPORTPATH "/sys/class/gpio/export"
|
||||
#define PWMEXPORTPATH "/sys/class/pwm/pwmchip%d/export"
|
||||
int read_dev_i(std::string path) {
|
||||
int val = -1;
|
||||
std::ifstream ifin(path.c_str());
|
||||
ifin >> val;
|
||||
return val;
|
||||
}
|
||||
|
||||
std::string read_dev_s(std::string path) {
|
||||
std::string val;
|
||||
std::ifstream ifin(path.c_str());
|
||||
ifin >> val;
|
||||
return val;
|
||||
}
|
||||
|
||||
DeviceExport::DeviceExport()
|
||||
{
|
||||
int num = sizeof(ports) / sizeof(ports[0]);
|
||||
for (int i = 0; i < num; i++)
|
||||
write_dev(IOEXPORTPATH, ports[i]);
|
||||
|
||||
num = sizeof(pwms) / sizeof(pwms[0]);
|
||||
for (int i = 0; i < num; i++)
|
||||
write_dev(utils::format_string(PWMEXPORTPATH, pwms[i]), 0);
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
|
||||
#define G300
|
||||
|
||||
template <typename T>
|
||||
void write_dev(std::string path, T value)
|
||||
{
|
||||
std::ofstream ofout(path);
|
||||
ofout << value;
|
||||
}
|
||||
|
||||
extern int read_dev_i(std::string path);
|
||||
|
||||
extern std::string read_dev_s(std::string path);
|
||||
|
||||
enum PORTS
|
||||
{
|
||||
Start = 171,
|
||||
Stop = 49,
|
||||
Power = 5,
|
||||
Fpga_Load = 8,
|
||||
|
||||
#ifndef G300
|
||||
Power_12v_Off = 12,
|
||||
#endif
|
||||
|
||||
MotorPower = 48,
|
||||
CuoZhiMotor_Reset = 56,
|
||||
CuoZhiMotor_Sleep = 57,
|
||||
CuoZhiMotor_Enable = 58,
|
||||
|
||||
CuoZhiMotor_Direction = 62,
|
||||
CuoZhiMotor_Decay = 63,
|
||||
CuoZhiMotor_Home = 184,
|
||||
CuoZhiMotor_Fault = 185,
|
||||
|
||||
CuoZhiMotor_Mode0 = 59,
|
||||
CuoZhiMotor_Mode1 = 60,
|
||||
CuoZhiMotor_Mode2 = 61,
|
||||
Cover = 189, // 'GPIO6A5' opened:0 ; closed:1
|
||||
|
||||
Paper = 225, // 'GPIO7B1' has paper:0 ; no paper:1
|
||||
Scan = 226, // 'GPIO7B2' no paper:0 ; has paper:1
|
||||
PaperJam = 102,
|
||||
Double_Paper = 219, // 'GPIO7A3' not doubled:0 ; doubled:1
|
||||
SW_NOR_FLASH = 221,
|
||||
Double_Enable = 250, // 'GPIO8A2' off: 0 ; on: 1
|
||||
|
||||
ZouZhiMotor_Reset = 64,
|
||||
ZouZhiMotor_Sleep = 65,
|
||||
ZouZhiMotor_Enable = 66,
|
||||
ZouZhiMotor_Direction = 70,
|
||||
|
||||
ZouZhiMotor_Decay = 71,
|
||||
ZouZhiMotor_Home = 187,
|
||||
ZouZhiMotor_Fault = 188,
|
||||
ZouZhiMotor_Mode0 = 67,
|
||||
|
||||
ZouZhiMotor_Mode1 = 68,
|
||||
ZouZhiMotor_Mode2 = 69,
|
||||
CIS_3v3_Off = 96,
|
||||
CIS_5v_En = 98,
|
||||
|
||||
Fpga_InitDone = 99,
|
||||
Image_In_Transfer = 101,
|
||||
Fpga_Reset = 232
|
||||
};
|
||||
|
||||
class DeviceExport
|
||||
{
|
||||
public:
|
||||
DeviceExport();
|
||||
|
||||
private:
|
||||
#ifndef G300
|
||||
const int ports[38] = {Start, Stop, Power, Fpga_Load, Power_12v_Off, MotorPower, CuoZhiMotor_Reset, CuoZhiMotor_Sleep, CuoZhiMotor_Enable,
|
||||
CuoZhiMotor_Direction, CuoZhiMotor_Decay, CuoZhiMotor_Home, CuoZhiMotor_Fault, CuoZhiMotor_Mode0,
|
||||
CuoZhiMotor_Mode1, CuoZhiMotor_Mode2, Cover, Paper, Scan, PaperJam, Double_Paper, Double_Enable,
|
||||
ZouZhiMotor_Reset, ZouZhiMotor_Sleep, ZouZhiMotor_Enable, ZouZhiMotor_Direction, ZouZhiMotor_Decay,
|
||||
ZouZhiMotor_Home, ZouZhiMotor_Fault, ZouZhiMotor_Mode0, ZouZhiMotor_Mode1, ZouZhiMotor_Mode2,
|
||||
CIS_3v3_Off, CIS_5v_En, Fpga_InitDone, Image_In_Transfer, Fpga_Reset, SW_NOR_FLASH};
|
||||
#else
|
||||
const int ports[36] = {Start, Stop, Power, Fpga_Load, MotorPower, CuoZhiMotor_Reset, CuoZhiMotor_Sleep, CuoZhiMotor_Enable,
|
||||
CuoZhiMotor_Direction, CuoZhiMotor_Decay, CuoZhiMotor_Home, CuoZhiMotor_Fault, CuoZhiMotor_Mode0,
|
||||
CuoZhiMotor_Mode1, CuoZhiMotor_Mode2, Cover, Paper, Scan, PaperJam, Double_Paper, Double_Enable,
|
||||
ZouZhiMotor_Reset, ZouZhiMotor_Sleep, ZouZhiMotor_Enable, ZouZhiMotor_Direction, ZouZhiMotor_Decay,
|
||||
ZouZhiMotor_Home, ZouZhiMotor_Fault, ZouZhiMotor_Mode0, ZouZhiMotor_Mode1, ZouZhiMotor_Mode2,
|
||||
CIS_3v3_Off, CIS_5v_En, Fpga_InitDone, Image_In_Transfer, Fpga_Reset};
|
||||
#endif
|
||||
const int pwms[2] = {2, 3};
|
||||
};
|
|
@ -0,0 +1,76 @@
|
|||
//
|
||||
// Created by yingluo907 on 2019/4/11.
|
||||
//
|
||||
#include "Gpio.h"
|
||||
|
||||
#include <base/utils.h>
|
||||
#include "DevUtil.h"
|
||||
|
||||
#define IOPATH "%s/gpio%d/%s"
|
||||
|
||||
const std::string Gpio::falling = "falling";
|
||||
const std::string Gpio::rising = "rising";
|
||||
const std::string Gpio::both = "both";
|
||||
const std::string Gpio::none = "none";
|
||||
|
||||
const std::string Gpio::in = "in";
|
||||
const std::string Gpio::out = "out";
|
||||
|
||||
Gpio::Gpio(int port)
|
||||
{
|
||||
this->port = port;
|
||||
path_value = utils::format_string(IOPATH, path_gpiobase.c_str(), port, path_value.c_str());
|
||||
path_edge = utils::format_string(IOPATH, path_gpiobase.c_str(), port, path_edge.c_str());
|
||||
path_direction = utils::format_string(IOPATH, path_gpiobase.c_str(), port, path_direction.c_str());
|
||||
path_active_low = utils::format_string(IOPATH, path_gpiobase.c_str(), port, path_active_low.c_str());
|
||||
}
|
||||
|
||||
int Gpio::getPort()
|
||||
{
|
||||
return port;
|
||||
}
|
||||
|
||||
void Gpio::setValue(GpioLevel level)
|
||||
{
|
||||
write_dev(path_value, level);
|
||||
}
|
||||
|
||||
Gpio::GpioLevel Gpio::getValue() {
|
||||
return (Gpio::GpioLevel)read_dev_i(path_value);
|
||||
}
|
||||
|
||||
std::string Gpio::getDirection()
|
||||
{
|
||||
return read_dev_s(path_direction);
|
||||
}
|
||||
|
||||
void Gpio::setDirection(std::string direction)
|
||||
{
|
||||
write_dev(path_direction, direction);
|
||||
}
|
||||
|
||||
void Gpio::setActive(GpioLevel level)
|
||||
{
|
||||
write_dev(path_active_low, level);
|
||||
}
|
||||
|
||||
Gpio::GpioLevel Gpio::getActive()
|
||||
{
|
||||
return (GpioLevel)read_dev_i(path_active_low);
|
||||
}
|
||||
|
||||
void Gpio::setEdge(std::string edge)
|
||||
{
|
||||
write_dev(path_edge, edge);
|
||||
}
|
||||
|
||||
std::string Gpio::getEdge()
|
||||
{
|
||||
return read_dev_s(path_edge);
|
||||
}
|
||||
|
||||
GpioOut::GpioOut(int port) :
|
||||
Gpio(port)
|
||||
{
|
||||
setDirection(out);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
|
||||
class Gpio
|
||||
{
|
||||
public:
|
||||
enum GpioLevel
|
||||
{
|
||||
Low,
|
||||
High
|
||||
};
|
||||
|
||||
Gpio(int port);
|
||||
int getPort();
|
||||
void setValue(GpioLevel level);
|
||||
GpioLevel getValue();
|
||||
std::string getDirection();
|
||||
void setDirection(std::string direction);
|
||||
void setActive(GpioLevel level);
|
||||
GpioLevel getActive();
|
||||
void setEdge(std::string edge);
|
||||
std::string getEdge();
|
||||
|
||||
std::string getValuePath()
|
||||
{
|
||||
return path_value;
|
||||
}
|
||||
|
||||
static const std::string falling;
|
||||
static const std::string rising;
|
||||
static const std::string both;
|
||||
static const std::string none;
|
||||
|
||||
static const std::string in;
|
||||
static const std::string out;
|
||||
|
||||
private:
|
||||
int port;
|
||||
const std::string path_gpiobase = "/sys/class/gpio";
|
||||
std::string path_value = "value";
|
||||
std::string path_edge = "edge";
|
||||
std::string path_direction = "direction";
|
||||
std::string path_active_low = "active_low";
|
||||
};
|
||||
|
||||
class GpioOut : public Gpio
|
||||
{
|
||||
public:
|
||||
GpioOut(int port);
|
||||
};
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
class IRegsAccess
|
||||
{
|
||||
public:
|
||||
virtual ~IRegsAccess(){};
|
||||
|
||||
virtual bool read(unsigned int addr, unsigned int& val) = 0;
|
||||
virtual bool write(unsigned int addr , const unsigned int val) = 0;
|
||||
};
|
|
@ -0,0 +1,582 @@
|
|||
/*!
|
||||
\file serialib.cpp
|
||||
\brief Class to manage the serial port
|
||||
\author Philippe Lucidarme (University of Angers) <serialib@googlegroups.com>
|
||||
\version 1.2
|
||||
\date 28 avril 2011
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
This is a licence-free software, it can be used by anyone who try to build a better world.
|
||||
*/
|
||||
|
||||
#include "serialib.h"
|
||||
|
||||
|
||||
#define FNDELAY O_NDELAY
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Constructor of the class serialib.
|
||||
*/
|
||||
// Class constructor
|
||||
serialib::serialib()
|
||||
{}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Destructor of the class serialib. It close the connection
|
||||
*/
|
||||
// Class desctructor
|
||||
serialib::~serialib()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//_________________________________________
|
||||
// ::: Configuration and initialization :::
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Open the serial port
|
||||
\param Device : Port name (COM1, COM2, ... for Windows ) or (/dev/ttyS0, /dev/ttyACM0, /dev/ttyUSB0 ... for linux)
|
||||
\param Bauds : Baud rate of the serial port.
|
||||
|
||||
\n Supported baud rate for Windows :
|
||||
- 110
|
||||
- 300
|
||||
- 600
|
||||
- 1200
|
||||
- 2400
|
||||
- 4800
|
||||
- 9600
|
||||
- 14400
|
||||
- 19200
|
||||
- 38400
|
||||
- 56000
|
||||
- 57600
|
||||
- 115200
|
||||
- 128000
|
||||
- 256000
|
||||
|
||||
\n Supported baud rate for Linux :\n
|
||||
- 110
|
||||
- 300
|
||||
- 600
|
||||
- 1200
|
||||
- 2400
|
||||
- 4800
|
||||
- 9600
|
||||
- 19200
|
||||
- 38400
|
||||
- 57600
|
||||
- 115200
|
||||
|
||||
\return 1 success
|
||||
\return -1 device not found
|
||||
\return -2 error while opening the device
|
||||
\return -3 error while getting port parameters
|
||||
\return -4 Speed (Bauds) not recognized
|
||||
\return -5 error while writing port parameters
|
||||
\return -6 error while writing timeout parameters
|
||||
*/
|
||||
char serialib::Open(const char *Device,const unsigned int Bauds)
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
// Open serial port
|
||||
hSerial = CreateFileA(Device, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (hSerial == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_FILE_NOT_FOUND)
|
||||
return -1; // Device not found
|
||||
return -2; // Error while opening the device
|
||||
}
|
||||
|
||||
// Set parameters
|
||||
DCB dcbSerialParams = {0}; // Structure for the port parameters
|
||||
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
|
||||
if (!GetCommState(hSerial, &dcbSerialParams)) // Get the port parameters
|
||||
return -3; // Error while getting port parameters
|
||||
switch (Bauds) // Set the speed (Bauds)
|
||||
{
|
||||
case 110:
|
||||
dcbSerialParams.BaudRate = CBR_110;
|
||||
break;
|
||||
case 300:
|
||||
dcbSerialParams.BaudRate = CBR_300;
|
||||
break;
|
||||
case 600:
|
||||
dcbSerialParams.BaudRate = CBR_600;
|
||||
break;
|
||||
case 1200:
|
||||
dcbSerialParams.BaudRate = CBR_1200;
|
||||
break;
|
||||
case 2400:
|
||||
dcbSerialParams.BaudRate = CBR_2400;
|
||||
break;
|
||||
case 4800:
|
||||
dcbSerialParams.BaudRate = CBR_4800;
|
||||
break;
|
||||
case 9600:
|
||||
dcbSerialParams.BaudRate = CBR_9600;
|
||||
break;
|
||||
case 14400:
|
||||
dcbSerialParams.BaudRate = CBR_14400;
|
||||
break;
|
||||
case 19200:
|
||||
dcbSerialParams.BaudRate = CBR_19200;
|
||||
break;
|
||||
case 38400:
|
||||
dcbSerialParams.BaudRate = CBR_38400;
|
||||
break;
|
||||
case 56000:
|
||||
dcbSerialParams.BaudRate = CBR_56000;
|
||||
break;
|
||||
case 57600:
|
||||
dcbSerialParams.BaudRate = CBR_57600;
|
||||
break;
|
||||
case 115200:
|
||||
dcbSerialParams.BaudRate = CBR_115200;
|
||||
break;
|
||||
case 128000:
|
||||
dcbSerialParams.BaudRate = CBR_128000;
|
||||
break;
|
||||
case 256000:
|
||||
dcbSerialParams.BaudRate = CBR_256000;
|
||||
break;
|
||||
default:
|
||||
return -4;
|
||||
}
|
||||
dcbSerialParams.ByteSize = 8; // 8 bit data
|
||||
dcbSerialParams.StopBits = ONESTOPBIT; // One stop bit
|
||||
dcbSerialParams.Parity = NOPARITY; // No parity
|
||||
if (!SetCommState(hSerial, &dcbSerialParams)) // Write the parameters
|
||||
return -5; // Error while writing
|
||||
|
||||
// Set TimeOut
|
||||
timeouts.ReadIntervalTimeout = 0; // Set the Timeout parameters
|
||||
timeouts.ReadTotalTimeoutConstant = MAXDWORD; // No TimeOut
|
||||
timeouts.ReadTotalTimeoutMultiplier = 0;
|
||||
timeouts.WriteTotalTimeoutConstant = MAXDWORD;
|
||||
timeouts.WriteTotalTimeoutMultiplier = 0;
|
||||
if (!SetCommTimeouts(hSerial, &timeouts)) // Write the parameters
|
||||
return -6; // Error while writting the parameters
|
||||
return 1; // Opening successfull
|
||||
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
struct termios options; // Structure with the device's options
|
||||
|
||||
// Open device
|
||||
fd = open(Device, O_RDWR | O_NOCTTY | O_NDELAY); // Open port
|
||||
if (fd == -1)
|
||||
return -2; // If the device is not open, return -1
|
||||
fcntl(fd, F_SETFL, FNDELAY); // Open the device in nonblocking mode
|
||||
|
||||
// Set parameters
|
||||
tcgetattr(fd, &options); // Get the current options of the port
|
||||
bzero(&options, sizeof(options)); // Clear all the options
|
||||
speed_t Speed;
|
||||
switch (Bauds) // Set the speed (Bauds)
|
||||
{
|
||||
case 110:
|
||||
Speed = B110;
|
||||
break;
|
||||
case 300:
|
||||
Speed = B300;
|
||||
break;
|
||||
case 600:
|
||||
Speed = B600;
|
||||
break;
|
||||
case 1200:
|
||||
Speed = B1200;
|
||||
break;
|
||||
case 2400:
|
||||
Speed = B2400;
|
||||
break;
|
||||
case 4800:
|
||||
Speed = B4800;
|
||||
break;
|
||||
case 9600:
|
||||
Speed = B9600;
|
||||
break;
|
||||
case 19200:
|
||||
Speed = B19200;
|
||||
break;
|
||||
case 38400:
|
||||
Speed = B38400;
|
||||
break;
|
||||
case 57600:
|
||||
Speed = B57600;
|
||||
break;
|
||||
case 115200:
|
||||
Speed = B115200;
|
||||
break;
|
||||
case 500000:
|
||||
Speed = B500000;
|
||||
break;
|
||||
case 921600:
|
||||
Speed = B921600;
|
||||
break;
|
||||
case 1500000:
|
||||
Speed = B1500000;
|
||||
break;
|
||||
default:
|
||||
return -4;
|
||||
}
|
||||
cfsetispeed(&options, Speed); // Set the baud rate at 115200 bauds
|
||||
cfsetospeed(&options, Speed);
|
||||
options.c_cflag |= (CLOCAL | CREAD | CS8); // Configure the device : 8 bits, no parity, no control
|
||||
options.c_iflag |= (IGNPAR | IGNBRK);
|
||||
options.c_cc[VTIME] = 0; // Timer unused
|
||||
options.c_cc[VMIN] = 0; // At least on character before satisfy reading
|
||||
tcsetattr(fd, TCSANOW, &options); // Activate the settings
|
||||
return (1); // Success
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Close the connection with the current device
|
||||
*/
|
||||
void serialib::Close()
|
||||
{
|
||||
#if defined (_WIN32) || defined( _WIN64)
|
||||
CloseHandle(hSerial);
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
close (fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//___________________________________________
|
||||
// ::: Read/Write operation on characters :::
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Write a char on the current serial port
|
||||
\param Byte : char to send on the port (must be terminated by '\0')
|
||||
\return 1 success
|
||||
\return -1 error while writting data
|
||||
*/
|
||||
char serialib::WriteChar(const char Byte)
|
||||
{
|
||||
#if defined (_WIN32) || defined( _WIN64)
|
||||
DWORD dwBytesWritten; // Number of bytes written
|
||||
if(!WriteFile(hSerial,&Byte,1,&dwBytesWritten,NULL)) // Write the char
|
||||
return -1; // Error while writing
|
||||
return 1; // Write operation successfull
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
if (write(fd,&Byte,1)!=1) // Write the char
|
||||
return -1; // Error while writting
|
||||
return 1; // Write operation successfull
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
//________________________________________
|
||||
// ::: Read/Write operation on strings :::
|
||||
|
||||
|
||||
/*!
|
||||
\brief Write a string on the current serial port
|
||||
\param String : string to send on the port (must be terminated by '\0')
|
||||
\return 1 success
|
||||
\return -1 error while writting data
|
||||
*/
|
||||
char serialib::WriteString(const char *String)
|
||||
{
|
||||
#if defined (_WIN32) || defined( _WIN64)
|
||||
DWORD dwBytesWritten; // Number of bytes written
|
||||
if(!WriteFile(hSerial,String,strlen(String),&dwBytesWritten,NULL)) // Write the string
|
||||
return -1; // Error while writing
|
||||
return 1; // Write operation successfull
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
int Lenght=strlen(String); // Lenght of the string
|
||||
if (write(fd,String,Lenght)!=Lenght) // Write the string
|
||||
return -1; // error while writing
|
||||
return 1; // Write operation successfull
|
||||
#endif
|
||||
}
|
||||
|
||||
// _____________________________________
|
||||
// ::: Read/Write operation on bytes :::
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Write an array of data on the current serial port
|
||||
\param Buffer : array of bytes to send on the port
|
||||
\param NbBytes : number of byte to send
|
||||
\return 1 success
|
||||
\return -1 error while writting data
|
||||
*/
|
||||
char serialib::Write(const void *Buffer, const unsigned int NbBytes)
|
||||
{
|
||||
#if defined (_WIN32) || defined( _WIN64)
|
||||
DWORD dwBytesWritten; // Number of byte written
|
||||
if(!WriteFile(hSerial, Buffer, NbBytes, &dwBytesWritten, NULL)) // Write data
|
||||
return -1; // Error while writing
|
||||
return 1; // Write operation successfull
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
if (write (fd,Buffer,NbBytes)!=(ssize_t)NbBytes) // Write data
|
||||
return -1; // Error while writing
|
||||
return 1; // Write operation successfull
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Wait for a byte from the serial device and return the data read
|
||||
\param pByte : data read on the serial device
|
||||
\param TimeOut_ms : delay of timeout before giving up the reading
|
||||
If set to zero, timeout is disable (Optional)
|
||||
\return 1 success
|
||||
\return 0 Timeout reached
|
||||
\return -1 error while setting the Timeout
|
||||
\return -2 error while reading the byte
|
||||
*/
|
||||
char serialib::ReadChar(char *pByte,unsigned int TimeOut_ms)
|
||||
{
|
||||
#if defined (_WIN32) || defined(_WIN64)
|
||||
|
||||
DWORD dwBytesRead = 0;
|
||||
timeouts.ReadTotalTimeoutConstant=TimeOut_ms; // Set the TimeOut
|
||||
if(!SetCommTimeouts(hSerial, &timeouts)) // Write the parameters
|
||||
return -1; // Error while writting the parameters
|
||||
if(!ReadFile(hSerial,pByte, 1, &dwBytesRead, NULL)) // Read the byte
|
||||
return -2; // Error while reading the byte
|
||||
if (dwBytesRead==0) return 0; // Return 1 if the timeout is reached
|
||||
return 1; // Success
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
TimeOut Timer; // Timer used for timeout
|
||||
Timer.InitTimer(); // Initialise the timer
|
||||
while (Timer.ElapsedTime_ms()<TimeOut_ms || TimeOut_ms==0) // While Timeout is not reached
|
||||
{
|
||||
switch (read(fd,pByte,1)) { // Try to read a byte on the device
|
||||
case 1 : return 1; // Read successfull
|
||||
case -1 : return -2; // Error while reading
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Read a string from the serial device (without TimeOut)
|
||||
\param String : string read on the serial device
|
||||
\param FinalChar : final char of the string
|
||||
\param MaxNbBytes : maximum allowed number of bytes read
|
||||
\return >0 success, return the number of bytes read
|
||||
\return -1 error while setting the Timeout
|
||||
\return -2 error while reading the byte
|
||||
\return -3 MaxNbBytes is reached
|
||||
*/
|
||||
int serialib::ReadStringNoTimeOut(char *String,char FinalChar,unsigned int MaxNbBytes)
|
||||
{
|
||||
unsigned int NbBytes=0; // Number of bytes read
|
||||
char ret; // Returned value from Read
|
||||
while (NbBytes<MaxNbBytes) // While the buffer is not full
|
||||
{ // Read a byte with the restant time
|
||||
ret=ReadChar(&String[NbBytes]);
|
||||
if (ret==1) // If a byte has been read
|
||||
{
|
||||
if (String[NbBytes]==FinalChar) // Check if it is the final char
|
||||
{
|
||||
String [++NbBytes]=0; // Yes : add the end character 0
|
||||
return NbBytes; // Return the number of bytes read
|
||||
}
|
||||
NbBytes++; // If not, just increase the number of bytes read
|
||||
}
|
||||
if (ret<0) return ret; // Error while reading : return the error number
|
||||
}
|
||||
return -3; // Buffer is full : return -3
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Read a string from the serial device (with timeout)
|
||||
\param String : string read on the serial device
|
||||
\param FinalChar : final char of the string
|
||||
\param MaxNbBytes : maximum allowed number of bytes read
|
||||
\param TimeOut_ms : delay of timeout before giving up the reading (optional)
|
||||
\return >0 success, return the number of bytes read
|
||||
\return 0 timeout is reached
|
||||
\return -1 error while setting the Timeout
|
||||
\return -2 error while reading the byte
|
||||
\return -3 MaxNbBytes is reached
|
||||
*/
|
||||
int serialib::ReadString(char *String,char FinalChar,unsigned int MaxNbBytes,unsigned int TimeOut_ms)
|
||||
{
|
||||
if (TimeOut_ms==0)
|
||||
return ReadStringNoTimeOut(String,FinalChar,MaxNbBytes);
|
||||
|
||||
unsigned int NbBytes=0; // Number of bytes read
|
||||
char ret; // Returned value from Read
|
||||
TimeOut Timer; // Timer used for timeout
|
||||
long int TimeOutParam;
|
||||
Timer.InitTimer(); // Initialize the timer
|
||||
|
||||
while (NbBytes<MaxNbBytes) // While the buffer is not full
|
||||
{ // Read a byte with the restant time
|
||||
TimeOutParam=TimeOut_ms-Timer.ElapsedTime_ms(); // Compute the TimeOut for the call of ReadChar
|
||||
if (TimeOutParam>0) // If the parameter is higher than zero
|
||||
{
|
||||
ret=ReadChar(&String[NbBytes],TimeOutParam); // Wait for a byte on the serial link
|
||||
if (ret==1) // If a byte has been read
|
||||
{
|
||||
|
||||
if (String[NbBytes]==FinalChar) // Check if it is the final char
|
||||
{
|
||||
String [++NbBytes]=0; // Yes : add the end character 0
|
||||
return NbBytes; // Return the number of bytes read
|
||||
}
|
||||
NbBytes++; // If not, just increase the number of bytes read
|
||||
}
|
||||
if (ret<0) return ret; // Error while reading : return the error number
|
||||
}
|
||||
if (Timer.ElapsedTime_ms()>TimeOut_ms) { // Timeout is reached
|
||||
String[NbBytes]=0; // Add the end caracter
|
||||
return 0; // Return 0
|
||||
}
|
||||
}
|
||||
return -3; // Buffer is full : return -3
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Read an array of bytes from the serial device (with timeout)
|
||||
\param Buffer : array of bytes read from the serial device
|
||||
\param MaxNbBytes : maximum allowed number of bytes read
|
||||
\param TimeOut_ms : delay of timeout before giving up the reading
|
||||
\return 1 success, return the number of bytes read
|
||||
\return 0 Timeout reached
|
||||
\return -1 error while setting the Timeout
|
||||
\return -2 error while reading the byte
|
||||
*/
|
||||
int serialib::Read (void *Buffer,unsigned int MaxNbBytes,unsigned int TimeOut_ms)
|
||||
{
|
||||
#if defined (_WIN32) || defined(_WIN64)
|
||||
DWORD dwBytesRead = 0;
|
||||
timeouts.ReadTotalTimeoutConstant=(DWORD)TimeOut_ms; // Set the TimeOut
|
||||
if(!SetCommTimeouts(hSerial, &timeouts)) // Write the parameters
|
||||
return -1; // Error while writting the parameters
|
||||
if(!ReadFile(hSerial,Buffer,(DWORD)MaxNbBytes,&dwBytesRead, NULL)) // Read the bytes from the serial device
|
||||
return -2; // Error while reading the byte
|
||||
if (dwBytesRead!=(DWORD)MaxNbBytes) return 0; // Return 0 if the timeout is reached
|
||||
return 1; // Success
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
TimeOut Timer; // Timer used for timeout
|
||||
Timer.InitTimer(); // Initialise the timer
|
||||
unsigned int NbByteRead=0;
|
||||
while (Timer.ElapsedTime_ms()<TimeOut_ms || TimeOut_ms==0) // While Timeout is not reached
|
||||
{
|
||||
unsigned char* Ptr=(unsigned char*)Buffer+NbByteRead; // Compute the position of the current byte
|
||||
int Ret=read(fd,(void*)Ptr,MaxNbBytes-NbByteRead); // Try to read a byte on the device
|
||||
if (Ret==-1) return -2; // Error while reading
|
||||
if (Ret>0) { // One or several byte(s) has been read on the device
|
||||
NbByteRead+=Ret; // Increase the number of read bytes
|
||||
if (NbByteRead>=MaxNbBytes) // Success : bytes has been read
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0; // Timeout reached, return 0
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// _________________________
|
||||
// ::: Special operation :::
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Empty receiver buffer (UNIX only)
|
||||
*/
|
||||
|
||||
void serialib::FlushReceiver()
|
||||
{
|
||||
#ifdef __linux__
|
||||
tcflush(fd,TCIFLUSH);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Return the number of bytes in the received buffer (UNIX only)
|
||||
\return The number of bytes in the received buffer
|
||||
*/
|
||||
int serialib::Peek()
|
||||
{
|
||||
int Nbytes=0;
|
||||
#ifdef __linux__
|
||||
ioctl(fd, FIONREAD, &Nbytes);
|
||||
#endif
|
||||
return Nbytes;
|
||||
}
|
||||
|
||||
// ******************************************
|
||||
// Class TimeOut
|
||||
// ******************************************
|
||||
|
||||
|
||||
/*!
|
||||
\brief Constructor of the class TimeOut.
|
||||
*/
|
||||
// Constructor
|
||||
TimeOut::TimeOut()
|
||||
{}
|
||||
|
||||
/*!
|
||||
\brief Initialise the timer. It writes the current time of the day in the structure PreviousTime.
|
||||
*/
|
||||
//Initialize the timer
|
||||
void TimeOut::InitTimer()
|
||||
{
|
||||
gettimeofday(&PreviousTime, NULL);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Returns the time elapsed since initialization. It write the current time of the day in the structure CurrentTime.
|
||||
Then it returns the difference between CurrentTime and PreviousTime.
|
||||
\return The number of microseconds elapsed since the functions InitTimer was called.
|
||||
*/
|
||||
//Return the elapsed time since initialization
|
||||
unsigned long int TimeOut::ElapsedTime_ms()
|
||||
{
|
||||
struct timeval CurrentTime;
|
||||
int sec,usec;
|
||||
gettimeofday(&CurrentTime, NULL); // Get current time
|
||||
sec=CurrentTime.tv_sec-PreviousTime.tv_sec; // Compute the number of second elapsed since last call
|
||||
usec=CurrentTime.tv_usec-PreviousTime.tv_usec; // Compute
|
||||
if (usec<0) { // If the previous usec is higher than the current one
|
||||
usec=1000000-PreviousTime.tv_usec+CurrentTime.tv_usec; // Recompute the microseonds
|
||||
sec--; // Substract one second
|
||||
}
|
||||
return sec*1000+usec/1000;
|
||||
}
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
/*!
|
||||
\file serialib.h
|
||||
\brief Serial library to communicate throught serial port, or any device emulating a serial port.
|
||||
\author Philippe Lucidarme (University of Angers) <serialib@googlegroups.com>
|
||||
\version 1.2
|
||||
\date 28 avril 2011
|
||||
This Serial library is used to communicate through serial port.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
This is a licence-free software, it can be used by anyone who try to build a better world.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SERIALIB_H
|
||||
#define SERIALIB_H
|
||||
|
||||
|
||||
// Used for TimeOut operations
|
||||
#include <sys/time.h>
|
||||
// Include for windows
|
||||
#if defined (_WIN32) || defined( _WIN64)
|
||||
// Accessing to the serial port under Windows
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
// Include for Linux
|
||||
#ifdef __linux__
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/shm.h>
|
||||
#include <termios.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
// File control definitions
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*! \class serialib
|
||||
\brief This class can manage a serial port. The class allows basic operations (opening the connection, reading, writing data and closing the connection).
|
||||
\example Example1.cpp
|
||||
*/
|
||||
|
||||
|
||||
class serialib
|
||||
{
|
||||
public:
|
||||
// Constructor of the class
|
||||
serialib ();
|
||||
|
||||
// Destructor
|
||||
~serialib ();
|
||||
|
||||
|
||||
|
||||
//_________________________________________
|
||||
// ::: Configuration and initialization :::
|
||||
|
||||
|
||||
// Open a device
|
||||
char Open (const char *Device,const unsigned int Bauds);
|
||||
|
||||
// Close the current device
|
||||
void Close();
|
||||
|
||||
|
||||
|
||||
//___________________________________________
|
||||
// ::: Read/Write operation on characters :::
|
||||
|
||||
|
||||
// Write a char
|
||||
char WriteChar (char);
|
||||
|
||||
// Read a char (with timeout)
|
||||
char ReadChar (char *pByte,const unsigned int TimeOut_ms=0);
|
||||
|
||||
|
||||
|
||||
//________________________________________
|
||||
// ::: Read/Write operation on strings :::
|
||||
|
||||
|
||||
// Write a string
|
||||
char WriteString (const char *String);
|
||||
// Read a string (with timeout)
|
||||
int ReadString ( char *String,
|
||||
char FinalChar,
|
||||
unsigned int MaxNbBytes,
|
||||
const unsigned int TimeOut_ms=0);
|
||||
|
||||
|
||||
|
||||
// _____________________________________
|
||||
// ::: Read/Write operation on bytes :::
|
||||
|
||||
|
||||
// Write an array of bytes
|
||||
char Write (const void *Buffer, const unsigned int NbBytes);
|
||||
|
||||
// Read an array of byte (with timeout)
|
||||
int Read (void *Buffer,unsigned int MaxNbBytes,const unsigned int TimeOut_ms=0);
|
||||
|
||||
|
||||
// _________________________
|
||||
// ::: Special operation :::
|
||||
|
||||
|
||||
// Empty the received buffer
|
||||
void FlushReceiver();
|
||||
|
||||
// Return the number of bytes in the received buffer
|
||||
int Peek();
|
||||
|
||||
private:
|
||||
// Read a string (no timeout)
|
||||
int ReadStringNoTimeOut (char *String,char FinalChar,unsigned int MaxNbBytes);
|
||||
|
||||
|
||||
#if defined (_WIN32) || defined( _WIN64)
|
||||
HANDLE hSerial;
|
||||
COMMTIMEOUTS timeouts;
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
int fd;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*! \class TimeOut
|
||||
\brief This class can manage a timer which is used as a timeout.
|
||||
*/
|
||||
// Class TimeOut
|
||||
class TimeOut
|
||||
{
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
TimeOut();
|
||||
|
||||
// Init the timer
|
||||
void InitTimer();
|
||||
|
||||
// Return the elapsed time since initialization
|
||||
unsigned long int ElapsedTime_ms();
|
||||
|
||||
private:
|
||||
struct timeval PreviousTime;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\mainpage serialib class
|
||||
|
||||
\brief
|
||||
\htmlonly
|
||||
<TABLE>
|
||||
<TR><TD>
|
||||
<a href="../serialibv1.2.zip" title="Download the serialib class">
|
||||
<TABLE>
|
||||
<TR><TD><IMG SRC="download.png" BORDER=0 WIDTH=100> </TD></TR>
|
||||
<TR><TD><P ALIGN="center">[Download]</P> </TD></TR>
|
||||
</TABLE>
|
||||
</A>
|
||||
</TD>
|
||||
<TD>
|
||||
<script type="text/javascript"><!--google_ad_client = "ca-pub-0665655683291467";
|
||||
google_ad_slot = "0230365165";
|
||||
google_ad_width = 728;
|
||||
google_ad_height = 90;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
\endhtmlonly
|
||||
|
||||
The class serialib offers simple access to the serial port devices for windows and linux. It can be used for any serial device (Built-in serial port, USB to RS232 converter, arduino board or any hardware using or emulating a serial port)
|
||||
\image html serialib.png
|
||||
The class can be used under Windows and Linux.
|
||||
The class allows basic operations like :
|
||||
- opening and closing connection
|
||||
- reading data (characters, array of bytes or strings)
|
||||
- writing data (characters, array of bytes or strings)
|
||||
- non-blocking functions (based on timeout).
|
||||
|
||||
|
||||
\author Philippe Lucidarme (University of Angers) <serialib@googlegroups.com>
|
||||
\date 1th may 2011 (Last update: 25th september 2012)
|
||||
\version 1.2
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
This is a licence-free software, it can be used by anyone who try to build a better world.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // SERIALIB_H
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
#include "uartregaccessb.h"
|
||||
|
||||
#include "serialib.h"
|
||||
|
||||
|
||||
UartRegsAccessB::UartRegsAccessB(std::string devName, int bauds, int readflag, int writeflag)
|
||||
{
|
||||
m_serial.reset(new serialib());
|
||||
m_serial->Open(devName.c_str(), bauds);
|
||||
this->readflag = readflag;
|
||||
this->writeflag = writeflag;
|
||||
}
|
||||
|
||||
UartRegsAccessB::~UartRegsAccessB()
|
||||
{
|
||||
}
|
||||
|
||||
bool UartRegsAccessB::write(unsigned int addr, unsigned int val)
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(mx_uart);
|
||||
unsigned char* pdata = bufSend;
|
||||
pdata[0] = writeflag;
|
||||
pdata[1] = (unsigned char)addr;
|
||||
*((unsigned int*)(pdata + 3)) = val;
|
||||
m_serial->Write(bufSend, sizeof(bufSend));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UartRegsAccessB::read(unsigned int addr, unsigned int& val)
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(mx_uart);
|
||||
unsigned char *pdata = bufRecv;
|
||||
pdata[0] = readflag;
|
||||
pdata[1] = (unsigned char)addr;
|
||||
m_serial->Write(bufRecv, 2);
|
||||
if (m_serial->Read(bufRecv, 5, 500))
|
||||
{
|
||||
val = *((unsigned int*)(bufRecv + 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
#include "regsaccess.h"
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
class serialib;
|
||||
|
||||
class UartRegsAccessB : public IRegsAccess
|
||||
{
|
||||
public:
|
||||
UartRegsAccessB(std::string devName, int bauds, int readflag, int writeflag);
|
||||
virtual ~UartRegsAccessB();
|
||||
|
||||
virtual bool read(unsigned int addr, unsigned int& val);
|
||||
virtual bool write(unsigned int addr, unsigned int val);
|
||||
|
||||
private:
|
||||
int readflag;
|
||||
int writeflag;
|
||||
unsigned char bufSend[7];
|
||||
unsigned char bufRecv[5];
|
||||
std::shared_ptr<serialib> m_serial;
|
||||
std::mutex mx_uart;
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
#include "uartregsaccess.h"
|
||||
#include "serialib.h"
|
||||
|
||||
UartRegsAccess::UartRegsAccess(std::string devName, int bauds, int readflag, int writeflag)
|
||||
: UartRegsAccessB(devName, bauds, readflag, writeflag)
|
||||
{
|
||||
}
|
||||
|
||||
UartRegsAccess::~UartRegsAccess()
|
||||
{
|
||||
}
|
||||
|
||||
bool UartRegsAccess::write(unsigned int addr, unsigned int val)
|
||||
{
|
||||
unsigned int valt = val;
|
||||
unsigned char* idata = (unsigned char*)&val;
|
||||
unsigned char *idatat = (unsigned char *)&valt;
|
||||
for(int i = 0; i < 4; i++)
|
||||
idata[3 - i] = idatat[i];
|
||||
|
||||
return UartRegsAccessB::write(addr, val);
|
||||
}
|
||||
|
||||
bool UartRegsAccess::read(unsigned int addr, unsigned int& val)
|
||||
{
|
||||
unsigned int valt = 0;
|
||||
if (UartRegsAccessB::read(addr, valt))
|
||||
{
|
||||
unsigned char *idata = (unsigned char *)&val;
|
||||
unsigned char *idatat = (unsigned char *)&valt;
|
||||
for (int i = 0; i < 4; i++)
|
||||
idata[3 - i] = idatat[i];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
#include "uartregaccessb.h"
|
||||
|
||||
class UartRegsAccess : public UartRegsAccessB
|
||||
{
|
||||
public:
|
||||
UartRegsAccess(std::string devName, int bauds, int readflag, int writeflag);
|
||||
virtual ~UartRegsAccess();
|
||||
|
||||
virtual bool read(unsigned int addr, unsigned int& val);
|
||||
virtual bool write(unsigned int addr, unsigned int val);
|
||||
};
|
|
@ -0,0 +1,12 @@
|
|||
add_rules("mode.debug", "mode.release")
|
||||
|
||||
target("hardware")
|
||||
set_kind("static")
|
||||
add_syslinks("pthread", "dl")
|
||||
add_includedirs("../sdk")
|
||||
add_files("*.cpp", "./cis/*.cpp", "./uart/*.cpp", "../sdk/base/*.c*", "../sdk/json/*.c*", "../sdk/sane_opt_json/*.c*")
|
||||
--add_deps("gusb", "applog")
|
||||
--add_rules("utils.bin2c",{linewidth = 32,extension = {".bin"}})
|
||||
--add_files("table.bin")
|
||||
add_packages("sdk")
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
#include <sane/sane_ex.h>
|
||||
#include <huagao/hgscanner_error.h>
|
||||
#include "scanner_const_opts.h"
|
||||
#include <hardware.h>
|
||||
|
||||
|
||||
|
||||
|
@ -59,14 +60,21 @@ async_scanner::async_scanner() : usb_(nullptr), cfg_mgr_(nullptr), scan_id_(0)
|
|||
cfg_mgr_ = new device_option(user, on_log);
|
||||
const_opts_ = new scanner_const_opts();
|
||||
cfg_mgr_->add(const_opts_);
|
||||
cfg_mgr_->add(cis_);
|
||||
|
||||
init();
|
||||
usb_ = new async_usb_gadget(bulk_handle, on_connect);
|
||||
last_err_ = usb_->last_error();
|
||||
}
|
||||
|
||||
async_scanner::~async_scanner()
|
||||
{
|
||||
if(cis_)
|
||||
{
|
||||
cis_->stop_scan();
|
||||
cis_->close();
|
||||
cis_->release();
|
||||
cis_ = nullptr;
|
||||
}
|
||||
if(usb_)
|
||||
{
|
||||
usb_->stop();
|
||||
|
@ -151,6 +159,7 @@ dyn_mem_ptr async_scanner::handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, pac
|
|||
}
|
||||
void async_scanner::init(void)
|
||||
{
|
||||
cis_ = new scanner_hw();
|
||||
}
|
||||
|
||||
dyn_mem_ptr async_scanner::handle_simple_roger(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required)
|
||||
|
|
|
@ -16,12 +16,14 @@ class image_capture;
|
|||
class img_processor;
|
||||
class gb_json;
|
||||
class scanner_const_opts;
|
||||
class scanner_hw;
|
||||
|
||||
class async_scanner : public refer
|
||||
{
|
||||
async_usb_gadget *usb_;
|
||||
device_option *cfg_mgr_;
|
||||
scanner_const_opts *const_opts_;
|
||||
async_usb_gadget *usb_ = nullptr;
|
||||
device_option *cfg_mgr_ = nullptr;
|
||||
scanner_const_opts *const_opts_ = nullptr;
|
||||
scanner_hw *cis_ = nullptr;
|
||||
|
||||
MUTEX locker_;
|
||||
uint32_t img_cnt_;
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
#ifndef VER_MAIN
|
||||
#define VER_MAIN 2
|
||||
#define VER_MINOR 0
|
||||
#define VER_DATE 20231218
|
||||
#define VER_BUILD 4
|
||||
#define VER_DATE 20231219
|
||||
#define VER_BUILD 1
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -29,6 +29,7 @@ static std::string device_opt_json[] = {
|
|||
// scanner_const_opts
|
||||
scanner_const_opts::scanner_const_opts(const char* dev_path) : root_(dev_path)
|
||||
{
|
||||
set_where("scanner_const_opts");
|
||||
init();
|
||||
}
|
||||
scanner_const_opts::~scanner_const_opts()
|
||||
|
|
|
@ -32,30 +32,30 @@ public:
|
|||
// "group": "关于",
|
||||
// "title": "USB-VID",
|
||||
// "desc": "设备制造商在USB组织的ID",
|
||||
// "type": "int",
|
||||
// "type": "string",
|
||||
// "fix-id": 34898,
|
||||
// "ui-pos": 10,
|
||||
// "auth": 0,
|
||||
// "readonly": true,
|
||||
// "size": 4,
|
||||
// "size": 16,
|
||||
// "auto": false,
|
||||
// "cur": 0,
|
||||
// "default": 0
|
||||
// "cur": "3072",
|
||||
// "default": "3072"
|
||||
// },
|
||||
// "dev-pid": {
|
||||
// "cat": "base",
|
||||
// "group": "关于",
|
||||
// "title": "USB-PID",
|
||||
// "desc": "设备在USB组织中的产品ID",
|
||||
// "type": "int",
|
||||
// "type": "string",
|
||||
// "fix-id": 34899,
|
||||
// "ui-pos": 11,
|
||||
// "auth": 0,
|
||||
// "readonly": true,
|
||||
// "size": 4,
|
||||
// "size": 16,
|
||||
// "auto": false,
|
||||
// "cur": 0,
|
||||
// "default": 0
|
||||
// "cur": "0306",
|
||||
// "default": "0306"
|
||||
// },
|
||||
// "dev-name": {
|
||||
// "cat": "base",
|
||||
|
@ -97,7 +97,7 @@ public:
|
|||
// "ui-pos": 14,
|
||||
// "auth": 0,
|
||||
// "readonly": true,
|
||||
// "size": 96,
|
||||
// "size": 32,
|
||||
// "auto": false,
|
||||
// "ownread": true,
|
||||
// "cur": "GB20231201",
|
||||
|
@ -113,7 +113,7 @@ public:
|
|||
// "ui-pos": 15,
|
||||
// "auth": 0,
|
||||
// "readonly": true,
|
||||
// "size": 96,
|
||||
// "size": 32,
|
||||
// "auto": false,
|
||||
// "ownread": true,
|
||||
// "cur": "G2393B0500",
|
||||
|
@ -131,8 +131,8 @@ public:
|
|||
// "readonly": true,
|
||||
// "size": 4,
|
||||
// "auto": false,
|
||||
// "cur": 0,
|
||||
// "default": 0
|
||||
// "cur": 450000,
|
||||
// "default": 450000
|
||||
// },
|
||||
// "ip-addr": {
|
||||
// "cat": "base",
|
||||
|
|
|
@ -3,10 +3,11 @@ add_rules("mode.debug", "mode.release")
|
|||
target("hgscanner")
|
||||
set_kind("binary")
|
||||
add_syslinks("pthread", "dl")
|
||||
add_includedirs("../sdk", "../usb")
|
||||
add_includedirs("../sdk", "../usb", "../sdk/imgprc/3rdsdk/include", "../hardware")
|
||||
add_files("*.cpp", "../sdk/base/*.c*", "../sdk/imgprc/*.c*", "../sdk/json/*.c*", "../sdk/sane_opt_json/*.c*")
|
||||
--add_deps("gusb", "applog")
|
||||
--add_rules("utils.bin2c",{linewidth = 32,extension = {".bin"}})
|
||||
--add_files("table.bin")
|
||||
add_packages("sdk")
|
||||
add_deps("usb")
|
||||
add_deps("hardware")
|
|
@ -47,7 +47,7 @@ enum cancel_io
|
|||
enum ep0_req
|
||||
{
|
||||
USB_REQ_EP0_GET_PEER_CONFIG = 100, // get protocol version (PROTOCOL_VER), req = me, ind = 0, val = 0, len = sizeof(PEERCFG)
|
||||
USB_REQ_EP0_GET_STATUS, // 获取各工作线程状态, return EP0REPLYSTATUS. req = me, ind = 0, val = 0, len = sizeof(EP0REPLYSTATUS)
|
||||
USB_REQ_EP0_GET_STATUS, // 获取各工作线程状态, return EP0REPLYSTATUS. req = me, ind = 0, val = bool: whether write log, len = sizeof(EP0REPLYSTATUS)
|
||||
USB_REQ_EP0_CANCEL_IO, // 设置当前IO数据的有效性. req = me, ind = 0, val = 0, len = sizeof(uint32_t), discard IO data when data is CANCEL_IO_CANCEL
|
||||
// work-flow: write control with 'CANCEL_IO_CANCEL', write bulk with 1 byte, write control with not 'CANCEL_IO_CANCEL' to restore
|
||||
USB_REQ_EP0_SET_ENCRYPT, // 设置加密方式, req = me, ind = 0, val = 0, len = sizeof(PACK_BASE)
|
||||
|
|
|
@ -94,6 +94,17 @@ namespace utils
|
|||
bool run_get_message(HWND hwnd, UINT filter_min = 0, UINT filter_max = 0, std::function<bool(MSG*, bool*)> msghandler = std::function<bool(MSG*, bool*)>());
|
||||
#endif
|
||||
|
||||
template<typename ... Args>
|
||||
std::string format_string(const char* fmt, Args ... args)
|
||||
{
|
||||
size_t size = snprintf(nullptr, 0, fmt, args ...) + 2;
|
||||
std::unique_ptr<char[]> buf(new char[size]);
|
||||
|
||||
snprintf(buf.get(), size, fmt, args ...);
|
||||
|
||||
return buf.get();
|
||||
}
|
||||
|
||||
template<typename ... Args>
|
||||
void to_log(int level, const char* fmt, Args ... args)
|
||||
{
|
||||
|
|
|
@ -103,6 +103,7 @@ enum opt_visible_level // "visible" field
|
|||
};
|
||||
|
||||
// sane-standard-option-name defined by third-app
|
||||
#define SANE_FULL_NAME(n) SANE_STD_OPT_NAME_##n
|
||||
//
|
||||
// PART I: 参数类型与华高一致,可直接通过改name字段为标准值实现
|
||||
#define SANE_STD_OPT_NAME_RESTORE "restore" // OPTION_TITLE_HFMRSZ
|
||||
|
@ -236,7 +237,22 @@ enum opt_visible_level // "visible" field
|
|||
#define SANE_STD_OPT_NAME_DUPLEX "duplex" // OPTION_TITLE_SMYM
|
||||
// END for sane-standard-option-name defined by third-app
|
||||
//
|
||||
//
|
||||
|
||||
// PART III: inner option on device
|
||||
#define SANE_STD_OPT_NAME_CIS_BAUD "baud"
|
||||
#define SANE_STD_OPT_NAME_CIS_DELAY "act-after"
|
||||
#define SANE_STD_OPT_NAME_CIS_FRAME_H "frame-h"
|
||||
#define SANE_STD_OPT_NAME_CIS_SAMPLE "sample"
|
||||
#define SANE_STD_OPT_NAME_CIS_EXPO_FB "expo-fb"
|
||||
#define SANE_STD_OPT_NAME_CIS_EXPO_FG "expo-fg"
|
||||
#define SANE_STD_OPT_NAME_CIS_EXPO_FR "expo-fr"
|
||||
#define SANE_STD_OPT_NAME_CIS_EXPO_BB "expo-bb"
|
||||
#define SANE_STD_OPT_NAME_CIS_EXPO_BG "expo-bg"
|
||||
#define SANE_STD_OPT_NAME_CIS_EXPO_BR "expo-br"
|
||||
#define SANE_STD_OPT_NAME_CIS_GAIN_FRONT "gain-f"
|
||||
#define SANE_STD_OPT_NAME_CIS_GAIN_BACK "gain-b"
|
||||
#define SANE_STD_OPT_NAME_CIS_OFFSET_FRONT "off-f"
|
||||
#define SANE_STD_OPT_NAME_CIS_OFFSET_BACK "off-b"
|
||||
//
|
||||
// 借鉴TWAIN协议固定ID的做法,定义SANE属性的固定ID - 这里与TWAIN中的ID保持一致,以方便TWAIN的调用
|
||||
enum sane_option_id
|
||||
|
|
|
@ -285,6 +285,7 @@ dyn_mem_ptr async_usb_gadget::handle_ctrl_setup(dyn_mem_ptr data)
|
|||
lps->task_required_bytes = want_bytes_task_;
|
||||
lps->packets_to_sent = sent_que_.size();
|
||||
lps->bytes_to_sent = want_bytes_in_;
|
||||
if(pev->u.setup.wValue)
|
||||
utils::log_mem_info("threads status:", lps, sizeof(*lps), LOG_LEVEL_DEBUG);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -64,7 +64,7 @@ target("conf")
|
|||
add_configfiles("config.h.in", {prefixdir = "header"})
|
||||
add_includedirs("$(buildir)/config/header", { public = true })
|
||||
|
||||
includes("usb", "scanner")
|
||||
includes("usb", "hardware", "scanner")
|
||||
|
||||
-- includes("regs", "deviceio", "motorboard", "capimage", "usb", "service", "scanner", "imgproc", "applog","scanservice","fpgaupdate","motorcontroller","display","testlcd","keymonitor","testkeymonitor","testdisplay","testwakeup")
|
||||
|
||||
|
|
Loading…
Reference in New Issue