rk3399_arm_lvds/usb/usbservice.cpp

245 lines
6.2 KiB
C++
Raw Normal View History

2024-03-05 03:46:18 +00:00
#include "usbservice.h"
#include <vector>
#include <string.h>
#include <iostream>
#include <linux/usb/ch9.h>
#include "stringex.hpp"
#include <unistd.h>
#include <fcntl.h>
#include "usbdevice.h"
#include "regsaccess.h"
#include "usbtransmit.h"
#include "usbreceive.h"
#include "usbnotify.h"
#include "applog.h"
static const std::string loggername = "UsbService";
typedef struct
{
int Command;
int Data;
int Length;
} USBCB;
#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
static bool read_regs(unsigned int *regs, int regindex, int creg, std::shared_ptr<IRegsAccess> &regsacess)
{
int index;
for (int i = 0; i < creg; i++)
{
index = regindex + i;
if (!regsacess->read(index, *(regs + i)))
{
LOG_ERROR(string_format("read error %d=%08x\n", index, regs[i]));
return false;
}
LOG_TRACE(string_format("read %d=%08x\n", index, regs[i]));
}
return true;
}
static bool write_regs(unsigned int *regs, int regindex, int creg, std::shared_ptr<IRegsAccess> &regsacess)
{
int index;
for (int i = 0; i < creg; i++)
{
index = regindex + i;
if (!regsacess->write(index, *(regs + i)))
{
LOG_ERROR(string_format("wirte error %d=%08x\n", index, regs[i]));
return false;
}
LOG_TRACE(string_format("wirte %d=%08x\n", index, regs[i]));
}
return true;
}
UsbService::UsbService(std::shared_ptr<IRegsAccess> fgparegs, std::shared_ptr<IRegsAccess> motorregs, std::shared_ptr<IRegsAccess> scannerregs)
{
LOG_INIT();
this->fgparegs = fgparegs;
this->motorregs = motorregs;
this->devregs = scannerregs;
auto ctrl_handle = [&](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 && this->fgparegs)
{
if (!read_regs(regs, regindex, creg, this->fgparegs))
return false;
::write(fd, buffer, setup->wLength);
return true;
}
break;
case USB_REQ_SET_FPGA_REGS:
if (!(setup->bRequestType & USB_DIR_IN) && creg && this->fgparegs)
{
::read(fd, buffer, setup->wLength);
if (!write_regs(regs, regindex, creg, this->fgparegs))
return false;
return true;
}
break;
case USB_REQ_GET_MOTOR_REGS:
if ((setup->bRequestType & USB_DIR_IN) && creg && this->motorregs)
{
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) && creg && this->motorregs)
{
::read(fd, buffer, setup->wLength);
if (!write_regs(regs, regindex, creg, this->motorregs))
return false;
return true;
}
break;
case USB_REQ_GET_DEV_REGS:
if ((setup->bRequestType & USB_DIR_IN) && creg && this->devregs)
{
//printf("ctrl read USB_REQ_GET_DEV_REGS addr = %d ->start \n",regindex);
if (!read_regs(regs, regindex, creg, this->devregs))
return false;
::write(fd, buffer, setup->wLength);
//printf("ctrl read USB_REQ_GET_DEV_REGS addr = %d ->end\n",regindex);
return true;
}
break;
case USB_REQ_SET_DEV_REGS:
if (!(setup->bRequestType & USB_DIR_IN) && creg && this->devregs)
{
//printf("ctrl write USB_REQ_SET_DEV_REGS addr = %d ->start\n",regindex);
::read(fd, buffer, setup->wLength);
if (!write_regs(regs, regindex, creg, this->devregs))
return false;
//printf("ctrl write USB_REQ_SET_DEV_REGS addr = %d ->end\n",regindex);
return true;
}
break;
case USB_REQ_ACCES_DEV_LOG:
if (setup->wLength != 64)
return false;
if (!(setup->bRequestType & USB_DIR_IN))
{
::read(fd, buffer, setup->wLength);
buffer[64 - 1] = 0;
logstring = (char *)buffer;
return true;
}
else
{
memset(buffer, 0, 64);
if (!logstring.empty())
memcpy(buffer, logstring.data(), logstring.size());
::write(fd, buffer, setup->wLength);
return true;
}
break;
case USB_REQ_GET_DEV_LOG:
if ((setup->wLength == 4) && (setup->bRequestType & USB_DIR_IN) && log_get_level(logstring, regindex, *((int *)regs)))
{
::write(fd, buffer, setup->wLength);
return true;
}
break;
case USB_REQ_SET_DEV_LOG:
if ((setup->wLength == 4) && !(setup->bRequestType & USB_DIR_IN))
{
::read(fd, buffer, setup->wLength);
return log_set_level(logstring, regindex, *((int *)regs));
}
break;
default:
break;
}
return false;
};
auto connected_call = [this](bool connected)
{
notify()->clear();
if (m_usbconnect)
m_usbconnect(connected);
LOG_TRACE(string_format("connect status:%s", connected ? "connected" : "disconnect"));
};
usb.reset(new UsbDevice(ctrl_handle, connected_call));
}
UsbService::~UsbService()
{
}
std::shared_ptr<ITransmit> UsbService::transmiter()
{
// if(transmit.get())
// {
// transmit.reset();
// }
// transmit.reset(new UsbTransmit(usb));
// return transmit;
return transmit ? transmit : (transmit = std::shared_ptr<ITransmit>(new UsbTransmit(usb)));
}
std::shared_ptr<IReceive> UsbService::receiver()
{
// if(receiv.get())
// {
// receiv.reset();
// }
// receiv.reset(new UsbReceive(usb));
// return receiv;
return receiv ? receiv : (receiv = std::shared_ptr<IReceive>(new UsbReceive(usb)));
}
void UsbService::set_scannerregs(std::shared_ptr<IRegsAccess> scannerregs)
{
this->devregs = scannerregs;
}
std::shared_ptr<INotify> UsbService::notify()
{
return noti ? noti : (noti = std::shared_ptr<INotify>(new UsbNotify(usb)));
}
void UsbService::set_onconnect_call(std::function<void(bool)> usbhotplugcall)
{
m_usbconnect = usbhotplugcall;
}