File FEBSlowcontrolInterface.h
File List > libmudaq > FEBSlowcontrolInterface.h
Go to the documentation of this file
/* Interface for slow control of the FEBs from the switching PCs
* Can work via optical link on the switching board or the MSCB
* bus on the backplane, once available */
// Niklaus Berger, January 2021 niberger@uni-mainz.de
#ifndef FEB_SLOWCONTROL_H
#define FEB_SLOWCONTROL_H
#include <deque>
#include <mutex>
#include <vector>
#include "../constants.h"
#include "../registers.h"
#include "mudaq_device.h"
using std::deque;
using std::vector;
class FEBSlowcontrolInterface {
public:
FEBSlowcontrolInterface(mudaq::MudaqDevice& mdev /*,Add midas connection here */);
virtual ~FEBSlowcontrolInterface();
// There should only be one SC interface, forbid copy and assignment
FEBSlowcontrolInterface() = delete;
FEBSlowcontrolInterface(const FEBSlowcontrolInterface&) = delete;
FEBSlowcontrolInterface& operator=(const FEBSlowcontrolInterface&) = delete;
virtual int FEB_write(uint32_t febIDx, const uint32_t startaddr, const vector<uint32_t>& data,
const bool nonincrementing = false, const bool broadcast = false,
const uint32_t MSTR_bar = 0);
virtual int FEB_write(uint32_t febIDx, const uint32_t startaddr, const uint32_t data);
virtual int FEB_broadcast(const uint32_t startaddr, const uint32_t data);
virtual int FEB_broadcast(const uint32_t startaddr, const vector<uint32_t>& data,
const bool nonincrementing = false);
virtual int FEB_ping(uint32_t febIDx);
// expects data vector with read-length size
virtual int FEB_read(uint32_t febIDx, const uint32_t startaddr, vector<uint32_t>& data,
const bool nonincrementing = false);
virtual int FEB_read(uint32_t febIDx, const uint32_t startaddr, uint32_t& data);
virtual void FEBEnable();
virtual void FEBsc_resetMain();
virtual void FEBsc_resetSecondary();
virtual int FEBsc_NiosRPC(uint32_t febIDx, uint16_t command,
vector<vector<uint32_t>> payload_chunks);
virtual void FPGAHistoInit(int febNumber, int chipNumber);
virtual void FPGAHistoStart();
virtual void FPGAHistoStop();
virtual uint32_t FPGAHistoGetContent(uint32_t idx);
virtual void write_register(uint32_t addr, uint32_t value);
enum ERRCODES {
ADDR_INVALID = -20,
SIZE_INVALID,
SIZE_ZERO,
FPGA_BUSY,
FPGA_TIMEOUT,
BAD_PACKET,
WRONG_SIZE,
NIOS_RPC_TIMEOUT,
OK = 0
};
enum OFFSETS { FEBsc_RPC_DATAOFFSET = 0 };
// TODO: Check what the corect addr is
enum ADDRS { BROADCAST_ADDR = 0xFFFFFFFF };
static constexpr uint32_t MIN_SC_MESSAGE_SIZE = 4;
protected:
mudaq::MudaqDevice& mdev;
std::mutex sc_mutex;
struct SC_reply_packet : public std::vector<uint32_t> {
public:
bool Good() {
// header+startaddr+length+trailer+[data]
if (size() < 4)
return false;
if (IsWR() && IsResponse())
return size() == 4; // No payload for write response
if (size() != GetLength() + 4)
return false;
return true;
};
// TODO: Remove hardcoded numbers here
bool IsRD() {
return (this->at(0) & 0x1f0000bc) == 0x1c0000bc + (PACKET_TYPE_SC_READ << 24) ||
(this->at(0) & 0x1f0000bc) ==
0x1c0000bc + (PACKET_TYPE_SC_READ_NONINCREMENTING << 24);
};
bool IsWR() {
return (this->at(0) & 0x1f0000bc) == 0x1c0000bc + (PACKET_TYPE_SC_WRITE << 24) ||
(this->at(0) & 0x1f0000bc) ==
0x1c0000bc + (PACKET_TYPE_SC_WRITE_NONINCREMENTING << 24);
};
uint16_t IsResponse() { return (this->at(2) & 0x10000) != 0; };
uint16_t GetFPGA_ID() { return (this->at(0) >> 8) & 0xffff; };
uint16_t GetStartAddr() { return this->at(1); };
size_t GetLength() {
if (IsWR() && IsResponse())
return 0;
else
return this->at(2) & 0xffff;
};
void Print();
};
deque<SC_reply_packet> sc_packet_deque;
SC_reply_packet FEBsc_pop_packet();
SC_reply_packet& FEBsc_peek_packet();
int FEBsc_read_packets();
uint32_t last_fpga_rmem_addr;
uint32_t m_FEBsc_wmem_addr;
uint32_t m_FEBsc_rmem_addr;
void rmenaddrIncr() {
m_FEBsc_rmem_addr =
(((m_FEBsc_rmem_addr + 1) == MUDAQ_MEM_RO_LEN) ? 0 : m_FEBsc_rmem_addr + 1);
}
};
#endif