ZT/sources/ExtModules/DI710Driver.cpp

403 lines
9.7 KiB
C++

#include "DI710Driver.h"
#include <QDebug>
#include <QElapsedTimer>
#include <iostream>
#include <cstring> // Needed for memset
#include <sys/socket.h> // Needed for the socket functions
#include <netdb.h> // Needed for the socket functions
#include <unistd.h>
CDI710Driver::CDI710Driver()
{
mRunThread = true;
mRunning = false;
mPendingOperation = DI710_NO_OPERATION;
}
unsigned int CDI710Driver::OpenDevice(QString IPAdress, int Port)
{
// int status;
// struct addrinfo host_info; // The struct that getaddrinfo() fills up with data.
// struct addrinfo *host_info_list; // Pointer to the to the linked list of host_info's.
// // The MAN page of getaddrinfo() states "All the other fields in the structure pointed
// // to by hints must contain either 0 or a null pointer, as appropriate." When a struct
// // is created in c++, it will be given a block of memory. This memory is not nessesary
// // empty. Therefor we use the memset function to make sure all fields are NULL.
// memset(&host_info, 0, sizeof host_info);
// std::cout << "Setting up the structs..." << std::endl;
// host_info.ai_family = AF_UNSPEC; // IP version not specified. Can be both.
// host_info.ai_socktype = SOCK_STREAM; // Use SOCK_STREAM for TCP or SOCK_DGRAM for UDP.
// // Now fill up the linked list of host_info structs with google's address information.
// status = getaddrinfo("www.google.com", "80", &host_info, &host_info_list);
// // getaddrinfo returns 0 on succes, or some other value when an error occured.
// // (translated into human readable text by the gai_gai_strerror function).
// if (status != 0) std::cout << "getaddrinfo error" << gai_strerror(status) ;
// std::cout << "Creating a socket..." << std::endl;
// int socketfd ; // The socket descripter
// socketfd = socket(host_info_list->ai_family, host_info_list->ai_socktype,
// host_info_list->ai_protocol);
// if (socketfd == -1) std::cout << "socket error " ;
// std::cout << "Connect()ing..." << std::endl;
// status = connect(socketfd, host_info_list->ai_addr, host_info_list->ai_addrlen);
// if (status == -1) std::cout << "connect error" ;
// std::cout << "send()ing message..." << std::endl;
// char *msg = "GET / HTTP/1.1\nhost: www.google.com\n\n";
// int len;
// ssize_t bytes_sent;
// len = strlen(msg);
// bytes_sent = send(socketfd, msg, len, 0);
// std::cout << "Waiting to recieve data..." << std::endl;
// ssize_t bytes_recieved;
// char incomming_data_buffer[1000];
// bytes_recieved = recv(socketfd, incomming_data_buffer,1000, 0);
// // If no data arrives, the program will just wait here until some data arrives.
// if (bytes_recieved == 0) std::cout << "host shut down." << std::endl ;
// if (bytes_recieved == -1)std::cout << "recieve error!" << std::endl ;
// std::cout << bytes_recieved << " bytes recieved :" << std::endl ;
// incomming_data_buffer[bytes_recieved] = '\0' ;
// std::cout << incomming_data_buffer << std::endl;
// std::cout << "Receiving complete. Closing socket..." << std::endl;
// freeaddrinfo(host_info_list);
// close(socketfd);
mDataQIPAddress.setAddress(IPAdress);
mDataQPort = Port;
mTCPSocket.setSocketOption(QAbstractSocket::LowDelayOption,1);
mTCPSocket.connectToHost(IPAdress,Port);
if(mTCPSocket.waitForConnected(5000) == true)
{
qDebug("DI710 device Connected");
return SetupDevice();
return DI710_RET_OK;
}
return DI710_RET_ERR_MODULE_OFFLINE;
}
void CDI710Driver::Run()
{
bool Run = true;
int Operation;
mRunning = true;
QElapsedTimer timer;
timer.start();
qDebug("DataQ thread started");
while(Run)
{
mTCPSocket.waitForReadyRead(200);
if(mTCPSocket.bytesAvailable() >= 2)
{
// QByteArray data = mTCPSocket.read(2);
// qint16 temp;
// QDataStream stream(&data,QIODevice::ReadOnly);
// stream.device()->seek(0);
// stream >> temp;
char data[2];
quint16 temp = 0;
mTCPSocket.read(data,2);
// data[3] = 0;
temp = data[1];
temp <<= 8;
temp += data[0];
mMutex.lockForWrite();
mCurData = (int)temp;
mMutex.unlock();
qDebug() << QByteArray(data,2).toHex() << " : " << temp;
//qDebug() << timer.elapsed();
// qDebug() << mTCPSocket.bytesAvailable();
timer.start();
}
mMutex.lockForRead();
//Run = mRunThread;
Operation = mPendingOperation;
mPendingOperation = DI710_NO_OPERATION;
mMutex.unlock();
switch(Operation)
{
case DI710_NO_OPERATION:
{
break;
}
case DI710_STOP_ACQUISITION_OPERATION:
{
SendStopAcquisitionFrame();
// qDebug("DataQ stop acquisition operation executed");
break;
}
case DI710_START_ACQUISITION_OPERATION:
{
SendStartAcquisitionFrame();
// qDebug("Dataq start acquisition operation executed");
break;
}
case DI710_STOP_THREAD_OPERATION:
{
SendStopAcquisitionFrame();
Run = false;
// qDebug("Dataq stop thread operation executed");
break;
}
case DI710_INVALID_OPERATION:
{
qDebug("Dataq invalid operation...");
break;
}
}
}
mMutex.lockForWrite();
mRunning = false;
mMutex.unlock();
// qDebug("DataQ thread stopped");
}
int CDI710Driver::GetAnalogData(int channel)
{
Q_UNUSED(channel)
int data = 0XDEADBEEF;
mMutex.lockForRead();
data = mCurData;
mMutex.unlock();
return data;
}
unsigned int CDI710Driver::SetupDevice()
{
mTCPSocket.readAll();
QByteArray data;
if(SendStopAcquisitionFrame() != DI710_RET_OK)
return DI710_RET_CANNOT_CONFIGURE;
data.clear();
data.append((char)0);
data.append("X00");
mTCPSocket.write(data);
if(mTCPSocket.waitForReadyRead(1000) == true)
{
qDebug() << mTCPSocket.readAll();
}
else
{
return DI710_RET_CANNOT_CONFIGURE;
}
data.clear();
data.append((char)0);
data.append("M000E");
mTCPSocket.write(data);
if(mTCPSocket.waitForReadyRead(1000) == true)
{
qDebug() << mTCPSocket.readAll();
}
else
{
return DI710_RET_CANNOT_CONFIGURE;
}
data.clear();
data.append((char)0);
data.append("L00F001");
mTCPSocket.write(data);
if(mTCPSocket.waitForReadyRead(1000) == true)
{
qDebug() << mTCPSocket.readAll();
}
else
{
return DI710_RET_CANNOT_CONFIGURE;
}
data.clear();
data.append((char)0);
data.append("C01");
mTCPSocket.write(data);
if(mTCPSocket.waitForReadyRead(1000) == true)
{
qDebug() << mTCPSocket.readAll();
}
else
{
return DI710_RET_CANNOT_CONFIGURE;
}
//Check if we can start...
if(SendStartAcquisitionFrame() != DI710_RET_OK)
return DI710_RET_CANNOT_CONFIGURE;
//stop for the moment...
if(SendStopAcquisitionFrame() != DI710_RET_OK)
return DI710_RET_CANNOT_CONFIGURE;
// mTCPSocket.setReadBufferSize(2);
return DI710_RET_OK;
}
int CDI710Driver::SendStopAcquisitionFrame()
{
bool done = false;
QByteArray data;
data.clear();
data.append((char)0);
data.append("T0");
mTCPSocket.setReadBufferSize(0);
mTCPSocket.readAll();
mTCPSocket.write(data);
QByteArray rxdata;
rxdata.clear();
while(done == false)
{
if(mTCPSocket.waitForReadyRead(1000) == true)
{
rxdata.append(mTCPSocket.readAll());
if(rxdata.contains("T0"))
{
done = true;
}
// qDebug() << rxdata;
}
else
{
return DI710_RET_CANNOT_CONFIGURE;
}
}
return DI710_RET_OK;
}
int CDI710Driver::SendStartAcquisitionFrame()
{
bool done = false;
QByteArray data;
data.clear();
data.append((char)0);
data.append("S3");
mTCPSocket.setReadBufferSize(0);
mTCPSocket.write(data);
QByteArray rxdata;
rxdata.clear();
while(done == false)
{
if(mTCPSocket.waitForReadyRead(1000) == true)
{
rxdata.append(mTCPSocket.read(1));
if(rxdata.contains("S3"))
{
done = true;
// qDebug() << rxdata;
}
}
else
{
qDebug() << rxdata;
return DI710_RET_CANNOT_CONFIGURE;
}
}
// mTCPSocket.setReadBufferSize(2);
return DI710_RET_OK;
}
void CDI710Driver::StopThread()
{
// mMutex.lockForWrite();
// mRunThread = false;
// mMutex.unlock();
mMutex.lockForWrite();
mPendingOperation = DI710_STOP_THREAD_OPERATION;
mMutex.unlock();
}
bool CDI710Driver::IsThreadRunning()
{
bool ret;
mMutex.lockForRead();
ret = mRunning;
mMutex.unlock();
return ret;
}
unsigned int CDI710Driver::StartAcquisition()
{
mMutex.lockForWrite();
mPendingOperation = DI710_START_ACQUISITION_OPERATION;
mMutex.unlock();
return DI710_RET_OK;
}
unsigned int CDI710Driver::StopAcquisition()
{
mMutex.lockForWrite();
mPendingOperation = DI710_STOP_ACQUISITION_OPERATION;
mMutex.unlock();
return DI710_RET_OK;
}
unsigned int CDI710Driver::GetAnalogInput(int Channel, int *Data)
{
Q_UNUSED(Channel)
*Data = GetAnalogData(0);
return DI710_RET_OK;
}