#ifndef DATARECEIVER_H #define DATARECEIVER_H #include #include #include #include #include #include // 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 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