HITDAQ/hit2023v2_RAWCAL/datareceiver.h

166 lines
4.7 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
{
// 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