Labrador/Desktop_Interface/unixusbdriver.h

99 lines
3.0 KiB
C++

#ifndef unixUsbDriver_H
#define unixUsbDriver_H
#include <QWidget>
#include <QThread>
#include <QMutex>
#include <QDateTime>
#include "genericusbdriver.h"
#include "libusb.h"
extern "C"
{
#include "libdfuprog.h"
}
#define MAX_ALLOWABLE_CUMULATIVE_FRAME_ERROR 50
//tcBlock is fed to the callback in the libusb user data section.
typedef struct tcBlock{
int number;
bool completed;
qint64 timeReceived;
} tcBlock;
//Oddly, libusb requires you to make a blocking libusb_handle_events() call in order to execute the callbacks for an asynchronous transfer.
//Since the call is blocking, this worker must exist in a separate, low priority thread!
class worker : public QObject
{
Q_OBJECT
public:
worker(){};
~worker(){};
libusb_context *ctx;
bool stopTime = false;
unsigned char cleanupRemaining = 4;
public slots:
void handle(){
qDebug() << "SUB THREAD ID" << QThread::currentThreadId();
while(cleanupRemaining){
//qDebug() << cleanupRemaining;
if(libusb_event_handling_ok(ctx)){
libusb_handle_events_timeout(ctx, &tv);
//qDebug() << "HANDLED";
}
if(stopTime){
if(cleanupRemaining){
cleanupRemaining--;
qDebug("Cleaning... #%hhu phases remain.\n", cleanupRemaining);
}
}
}
qDebug() << "Cleanup complete"; //THIS THREAD STILL EXISTS
}
};
//This is the actual unixUsbDriver
//It handles the Mac/Linux specific parts of USB communication, through libusb.
//See genericUsbDriver for the non-platform-specific parts.
class unixUsbDriver : public genericUsbDriver
{
Q_OBJECT
public:
explicit unixUsbDriver(QWidget *parent = 0);
~unixUsbDriver();
void usbSendControl(uint8_t RequestType, uint8_t Request, uint16_t Value, uint16_t Index, uint16_t Length, unsigned char *LDATA);
char *isoRead(unsigned int *newLength);
void manualFirmwareRecovery(void);
protected:
//USB Vars
libusb_context *ctx = NULL;
libusb_device_handle *handle = NULL;
//USBIso Vars
unsigned char *midBuffer_current[NUM_ISO_ENDPOINTS];
unsigned char *midBuffer_prev[NUM_ISO_ENDPOINTS];
qint64 midBufferOffsets[NUM_ISO_ENDPOINTS];
libusb_transfer *isoCtx[NUM_ISO_ENDPOINTS][NUM_FUTURE_CTX] = { };
tcBlock transferCompleted[NUM_ISO_ENDPOINTS][NUM_FUTURE_CTX];
unsigned char dataBuffer[NUM_ISO_ENDPOINTS][NUM_FUTURE_CTX][ISO_PACKET_SIZE*ISO_PACKETS_PER_CTX];
worker *isoHandler = nullptr;
QThread *workerThread = nullptr;
int cumulativeFramePhaseErrors = 0;
//Generic Functions
virtual unsigned char usbInit(unsigned long VIDin, unsigned long PIDin);
int usbIsoInit(void);
virtual int flashFirmware(void);
bool allEndpointsComplete(int n);
bool shutdownMode = false;
int numCancelled = 0;
signals:
public slots:
void isoTimerTick(void);
void recoveryTick(void);
void shutdownProcedure(void);
void backupCleanup(void);
};
#endif // unixUsbDriver_H