166 lines
4.8 KiB
C++
166 lines
4.8 KiB
C++
#ifndef DATARECEIVER_H
|
|
#define DATARECEIVER_H
|
|
|
|
#include <QObject>
|
|
#include <QUdpSocket>
|
|
#include <QTimer>
|
|
#include <QThread>
|
|
#include <QSemaphore>
|
|
#include <cstring> // For std::memcpy
|
|
|
|
#include "cbuffer.h"
|
|
|
|
#define DATA_PACKET_HEADER_SIZE 6
|
|
#define DATA_SYNC_HEADER_SIZE 6
|
|
#define DATA_RMS_FRAME_SIZE 16 // 8 unsigned shorts
|
|
#define DATA_BYTES_PER_SAMPLE 8 // RAW1RAW2+CAL1+CAL2
|
|
#define DATA_SAMPLES_PER_SENSOR 32 //grab 2 channels per sample RAW1+RAW2
|
|
#define DATA_MAX_SENSORS_PER_BOARD 5
|
|
#define DATA_MAX_BUNCH 16 // Max. product of dmaBunch * ethBunch
|
|
|
|
//#define DATA_BLOCK_SIZE (DATA_SENSORS_PER_BOARD * DATA_SAMPLES_PER_SENSOR * DATA_BYTES_PER_SAMPLE)
|
|
#define DATA_BLOCK_SIZE (sensorsPerBoard * DATA_SAMPLES_PER_SENSOR * DATA_BYTES_PER_SAMPLE)
|
|
#define DATA_PACKET_SIZE ( DATA_MAX_BUNCH * (DATA_PACKET_HEADER_SIZE + DATA_SYNC_HEADER_SIZE + DATA_BLOCK_SIZE + DATA_RMS_FRAME_SIZE ) )
|
|
|
|
#define DATA_MAX_BLOCK_SIZE (DATA_MAX_SENSORS_PER_BOARD * DATA_SAMPLES_PER_SENSOR * DATA_BYTES_PER_SAMPLE)
|
|
#define DATA_MAX_PACKET_SIZE ( DATA_MAX_BUNCH * (DATA_PACKET_HEADER_SIZE + DATA_SYNC_HEADER_SIZE + DATA_MAX_BLOCK_SIZE + DATA_RMS_FRAME_SIZE ) )
|
|
|
|
#define RECEIVER_BUFFER_SIZE 10000
|
|
|
|
#define RECEIVER_TIMER_PERIOD_MS 200 // The period of the timer to measure data rate. The measurement is always properly scaled.
|
|
#define RECEIVER_FRAMES_PER_SIG 100 // The DataReady signal is transmitted only every N frames, not to overload queued signals framework.
|
|
|
|
typedef struct SyncFrame
|
|
{
|
|
// unsigned short channel_id;
|
|
unsigned short local_ctr;
|
|
unsigned short global_ctr;
|
|
unsigned short sma_state;
|
|
// These fields are additional compared to STM side
|
|
unsigned short dummy = 0xFFFF; // For nice structure packing
|
|
int device_nr;
|
|
int data_ok;
|
|
} SyncFrame;
|
|
|
|
typedef struct {
|
|
unsigned short mean;
|
|
unsigned short sigma;
|
|
unsigned short max;
|
|
unsigned short status;
|
|
unsigned short registers[4];
|
|
} RMSFrame;
|
|
|
|
class BufferData
|
|
{
|
|
public:
|
|
SyncFrame sync_frame;
|
|
RMSFrame rms_frame;
|
|
int buffer_size;
|
|
|
|
struct SensorData {
|
|
unsigned short raw1; // First 16-bit unsigned short
|
|
unsigned short raw2; // Second 16-bit unsigned short
|
|
signed short cal1; // First 16-bit signed short
|
|
signed short cal2; // Second 16-bit signed short
|
|
};
|
|
SensorData* sensorData; // Renamed from sensor_data
|
|
|
|
BufferData() : buffer_size(0), sensorData(nullptr) {}
|
|
|
|
BufferData(int size) : buffer_size(0), sensorData(nullptr)
|
|
{
|
|
resize(size);
|
|
}
|
|
|
|
void resize(int size)
|
|
{
|
|
if (size == buffer_size)
|
|
return; // No need to change
|
|
if (sensorData)
|
|
{
|
|
delete[] sensorData;
|
|
sensorData = nullptr;
|
|
}
|
|
buffer_size = size;
|
|
if (size) // Do not allocate memory for an empty buffer
|
|
sensorData = new SensorData[size];
|
|
}
|
|
|
|
BufferData(const BufferData& master) : buffer_size(0), sensorData(nullptr)
|
|
{
|
|
sync_frame = master.sync_frame;
|
|
rms_frame = master.rms_frame;
|
|
resize(master.buffer_size);
|
|
std::memcpy(sensorData, master.sensorData, buffer_size * sizeof(SensorData));
|
|
}
|
|
|
|
BufferData& operator=(const BufferData& master)
|
|
{
|
|
if (this == &master)
|
|
return *this; // Self-assignment
|
|
sync_frame = master.sync_frame;
|
|
rms_frame = master.rms_frame;
|
|
resize(master.buffer_size);
|
|
std::memcpy(sensorData, master.sensorData, buffer_size * sizeof(SensorData));
|
|
return *this;
|
|
}
|
|
|
|
~BufferData()
|
|
{
|
|
resize(0); // :)
|
|
}
|
|
};
|
|
|
|
typedef CBuffer<BufferData> DataBuffer;
|
|
|
|
class DataReceiver : public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit DataReceiver(QObject *parent = nullptr);
|
|
~DataReceiver();
|
|
|
|
void configureEthSettings(QHostAddress address_to_set, quint16 port_to_set);
|
|
void configureBunchSize(int dma, int eth);
|
|
void outputEnable(int en);
|
|
|
|
int frameRate = 0;
|
|
int devNr = 0;
|
|
int sensorsPerBoard = 5;
|
|
|
|
DataBuffer dataBuffer;
|
|
|
|
signals:
|
|
void sigInit();
|
|
void sigDeinit();
|
|
void sigConfigureEthSettings();
|
|
void sigDataReady(DataReceiver* ptr);
|
|
|
|
public slots:
|
|
void onTimer();
|
|
|
|
protected:
|
|
void init();
|
|
void deinit();
|
|
QThread thread;
|
|
QSemaphore initSemaphore;
|
|
QTimer* timer = nullptr;
|
|
QUdpSocket* dataSocket = nullptr;
|
|
QHostAddress address;
|
|
quint16 port;
|
|
int outputEnabled = 0;
|
|
int dmaBunch = 1;
|
|
int ethBunch = 1;
|
|
char tmpBuffer[DATA_MAX_PACKET_SIZE];
|
|
int framesReceived = 0; // To calculate frame rate
|
|
int framesFromLastSig = 0;
|
|
|
|
protected slots:
|
|
void readData();
|
|
void onInit();
|
|
void onDeinit();
|
|
void onConfigureEthSettings();
|
|
};
|
|
|
|
#endif // DATARECEIVER_H
|