Commit 64045485 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

Merge branch 'wic-sw-monitoring'

parents 0f4bd87e d1d874a3
This diff is collapsed.
......@@ -21,22 +21,100 @@
#include <QtCore>
#include <QObject>
#include <QFrame>
#include <vector>
#include <memory>
#include <libmfipp.h>
#include <diot_crate.h>
class DiotController;
class DiotIOController;
class QDialog;
class QGroupBox;
class QLabel;
class QPushButton;
class DiotSlot : public QObject {
/**
* Class representing the DIOT crate hardware in the Qt world.
* It initalizes the hardware and provides signals and slots to other classes.
*/
class DiotHardware : public QObject {
Q_OBJECT
public:
/**
* Constructor.
* @param address is the FIP agent address of the crate.
* @param slots_nr is the number of I/O cards in the crate.
*/
DiotHardware(int address, int slots_nr);
/**
* Start the WorldFIP cycle.
*/
void Start();
DIOT_Crate* GetCrate() const
{
return crate.get();
}
public slots:
/**
* Change the output state for a card in a particular slot.
* @param slot is the card number (indexing from 0).
* @param state is the new output state.
*/
void SetOutput(int slot, unsigned int state);
signals:
/**
* Signal emitted on every macrocycle, provides information about inputs state.
* @param slot is the card number (indexing from 0).
* @param state is the inputs state.
*/
void InputChanged(int slot, unsigned int state);
/**
* Signal emitted on every macrocycle, provides information about fan state.
* @param fan is the fan number (indexing from 0).
* @param state is the fan state (true == operational, false == failure).
* @param rpm is the fan speed (expressed in RPM).
*/
void FanChanged(unsigned int fan, bool state, int rpm);
/**
* Signal emitted on every macrocycle, provides information about temperature.
* @param sensor is the sensor number (indexing from 0).
* @param state is the fan state (true == operational, false == failure).
* @param temp is the temperature (Celsius degrees).
*/
void TemperatureChanged(unsigned int sensor, bool state, int temp);
/**
* Signal emitted on every macrocycle, provides information about voltage.
* @param volt is the voltage number (indexing from 0).
* @param state is the voltage state (true == operational, false == failure).
* @see DIOT_Crate::GetVoltages()
*/
void VoltageChanged(unsigned int volt, bool state);
private:
std::unique_ptr<MasterFIP> mfip;
std::unique_ptr<CycleSimple> cycle;
std::unique_ptr<DIOT_Crate> crate;
mstrfip_hw_cfg hw_cfg;
mstrfip_sw_cfg sw_cfg;
};
/**
* Widget representing a single I/O card in the crate.
*/
class DiotIOCard : public QFrame {
Q_OBJECT
public:
DiotSlot(QDialog* parent, DiotController& controller, int num, int idx);
virtual ~DiotSlot() {}
DiotIOCard(QDialog* parent, DiotHardware& hw, int num, int idx);
virtual ~DiotIOCard() {}
unsigned int GetInput() const {
return vec_to_int(inputs);
......@@ -62,36 +140,64 @@ protected:
static unsigned int vec_to_int(const std::vector<bool>& vec);
static bool int_to_vec(unsigned int integer, std::vector<bool>& vec);
DiotController& controller;
std::vector<bool> inputs, outputs;
std::vector<QPushButton*> btn_state, btn_test;
QGroupBox* groupBox;
const int slot_nr;
const int io_count;
};
class DiotController : public QObject {
/**
* Widget grouping the I/O cards.
*/
class DiotIOController : public QFrame {
Q_OBJECT
public:
DiotController(QDialog* dialog, int address, int slots_nr);
void Start();
DiotIOController(QDialog* dialog, DiotHardware& hw, int slots_count);
public slots:
void UpdateInput(int slot, unsigned int state);
void SetOutput(int slot, unsigned int state);
signals:
void InputChanged(int slot, unsigned int state);
private:
std::vector<std::unique_ptr<DiotIOCard>> io_slots;
static constexpr unsigned int IO_PER_SLOT = 16;
};
/**
* Widget displaying diagnostic data obtained from the crate.
*/
class DiotDiag : public QFrame {
Q_OBJECT
public:
DiotDiag(QDialog* parent, DiotHardware& hw);
virtual ~DiotDiag() {}
public slots:
void UpdateFan(unsigned int fan, bool state, int rpm)
{
qDebug() << "fan " << fan << " state: " << state << " RPM: " << rpm;
updateLabel(fan_lbl, fan, state, "Fan", rpm);
}
void UpdateTemperature(unsigned int sensor, bool state, int temp)
{
qDebug() << "temperature " << sensor << " state: " << state << " value: " << temp;
updateLabel(temp_lbl, sensor, state, "Temperature", temp);
}
void UpdateVoltage(unsigned int volt, bool state);
private:
std::vector<std::unique_ptr<DiotSlot>> io_slots;
std::unique_ptr<MasterFIP> mfip;
std::unique_ptr<CycleSimple> cycle;
std::unique_ptr<DIOT_Crate> crate;
mstrfip_hw_cfg hw_cfg;
mstrfip_sw_cfg sw_cfg;
// Helper function to update labels
void updateLabel(std::vector<QLabel*> labels,
unsigned int idx, bool state, const QString& desc, int val);
std::vector<QLabel*> fan_lbl;
std::vector<QLabel*> temp_lbl;
std::vector<QLabel*> volt_lbl;
};
#endif /* CONTROLLER_H */
......@@ -17,6 +17,7 @@
*/
#include "diot_crate.h"
#include <limits>
void DIOT_Crate::SetOutput(int slot, int idx, bool state)
{
......@@ -28,7 +29,7 @@ void DIOT_Crate::SetOutput(int slot, int idx, bool state)
const uint8_t io_mask = getIOMask(idx);
uint8_t data = GetProdVarData(var_offset);
if((data & io_mask) == state)
if ((data & io_mask) == state)
return; // no update needed
if (state)
......@@ -73,7 +74,7 @@ uint32_t DIOT_Crate::GetSlotInputs(int slot)
{ // mutex locked scope
auto lock = getConsLock();
for(int i = 3; i >= 0; --i) {
for (int i = 3; i >= 0; --i) {
ret <<= 8;
ret |= getConsDataLock(var_offset + i, lock);
}
......@@ -81,3 +82,83 @@ uint32_t DIOT_Crate::GetSlotInputs(int slot)
return ret;
}
bool DIOT_Crate::GetFanStatus(unsigned int fan)
{
if (fan >= FAN_COUNT)
return false;
int status = GetFanStatusAll();
// status bit == 1 indicates failure, hence negation
return !(status & (1 << fan));
}
int DIOT_Crate::GetFanRPM(unsigned int fan)
{
if (fan >= FAN_COUNT)
return std::numeric_limits<int>::min();
int rpm = 0;
{ // mutex locked scope
auto lock = getConsLock();
rpm = (int) getConsDataLock(FAN0_SPEED + fan * 2, lock) << 8;
rpm |= getConsDataLock(FAN0_SPEED + fan * 2 + 1, lock);
}
return rpm;
}
bool DIOT_Crate::GetTempStatus(unsigned int sensor)
{
if (sensor >= TEMP_COUNT)
return false;
int status = GetTempStatusAll();
// status bit == 1 indicates failure, hence negation
return !(status & (1 << sensor));
}
int DIOT_Crate::GetTemp(unsigned int sensor)
{
if (sensor >= TEMP_COUNT)
return std::numeric_limits<int>::min();
return GetConsVarData(TEMPERATURE0 + sensor);
}
bool DIOT_Crate::GetVoltStatus(VOLTAGE volt)
{
// status bit == 1 indicates failure, hence negation
return !(GetVoltStatusAll() & volt);
}
std::string DIOT_Crate::GetVoltName(VOLTAGE volt)
{
for (const auto& volt_pair : VOLTAGES) {
if (volt_pair.first == volt)
return volt_pair.second;
}
return "UNKNOWN";
}
DIOT_Crate::VOLTAGE DIOT_Crate::GetVoltEnum(unsigned int idx)
{
if (idx >= VOLTAGES.size())
return INVALID;
return VOLTAGES[idx].first;
}
const std::vector<std::pair<DIOT_Crate::VOLTAGE, std::string>> DIOT_Crate::VOLTAGES =
{ { P3V3, "+3.3V" }, { P5V0, "+5V" },
{ P12V0, "+12V" }, { M12V0, "-12V" } };
......@@ -76,6 +76,119 @@ public:
return card_count;
}
/**
* Return the number of fans.
*/
unsigned int GetFanCount() const
{
return FAN_COUNT;
}
/**
* Return status of a particular fan.
* @param fan is the fan number (0 < fan < FAN_COUNT).
* @return True when functional.
*/
bool GetFanStatus(unsigned int fan);
/**
* Return status of all fans.
* @return 0 when all fans are functional, else check which bits are
* asserted to determine which fans are faulty.
*/
int GetFanStatusAll()
{
return GetConsVarData(FANS_STATUS);
}
/**
* Return speed of a particular fan.
* @param fan is the fan number (0 < fan < FAN_COUNT).
* @return Fan speed (RPM).
*/
int GetFanRPM(unsigned int fan);
/**
* Return the number of temperature sensors.
*/
unsigned int GetTempCount() const
{
return TEMP_COUNT;
}
/**
* Return status of a particular temperature sensor.
* @param sensor is the sensor number (0 < sensor < TEMP_COUNT).
* @return True when functional.
*/
bool GetTempStatus(unsigned int sensor);
/**
* Return status of all temperature sensors.
* @return 0 when all temperature sensors are functional, else check which
* bits is asserted to determine which sensors are faulty.
*/
int GetTempStatusAll()
{
return GetConsVarData(TEMP_STATUS);
}
/**
* Return temperature read from a particular sensor.
* @param sensor is the sensor number (0 < sensor < TEMP_COUNT).
* @return Temperature (Celsius degrees).
*/
int GetTemp(unsigned int sensor);
///> Voltage status flags
enum VOLTAGE {
P3V3 = 0x01,
P5V0 = 0x02,
P12V0 = 0x04,
M12V0 = 0x08,
INVALID = 0xff
};
/**
* Return power supply status.
* @return 0 when all voltages are correct, else check which bits are
* asserted to determine faulty voltages.
* @see VOLTAGE
*/
int GetVoltStatusAll()
{
return GetConsVarData(VOLT_STATUS);
}
/**
* Return status of a particular votlage.
* @param volt is the checked voltage.
* @return True when voltage is correct, false otherwise.
*/
bool GetVoltStatus(VOLTAGE volt);
/**
* Return vector of available voltage enums and their descriptions.
*/
static const std::vector<std::pair<VOLTAGE, std::string>>& GetVoltages()
{
return VOLTAGES;
}
/**
* Return a string describing a voltage.
*/
static std::string GetVoltName(VOLTAGE volt);
/**
* Return voltage enum corresponding to a particular index or INVALID
* if idx is out of bounds.
*/
static VOLTAGE GetVoltEnum(unsigned int idx);
private:
///> Return variable offset corresponding to a particular I/O and slot.
static int getVarOffset(int slot, int idx)
......@@ -97,6 +210,63 @@ private:
///> Number of I/O cards installed in the crate
const int card_count;
///> Number of fans
static constexpr unsigned int FAN_COUNT = 3;
///> Number of temperature sensors
static constexpr unsigned int TEMP_COUNT = 6;
///> Vector storing all voltages
static const std::vector<std::pair<VOLTAGE, std::string>> VOLTAGES;
///> Produced variable map
enum PRODUCED_VAR_MAP {
SLOT1_OUT_STATE = 0,
SLOT2_OUT_STATE = 4,
SLOT3_OUT_STATE = 8,
SLOT4_OUT_STATE = 12,
SLOT5_OUT_STATE = 16,
SLOT6_OUT_STATE = 20,
SLOT7_OUT_STATE = 24,
SLOT8_OUT_STATE = 28
};
///> Consumed variable map
enum CONSUMED_VAR_MAP {
SLOT1_IN_STATE = 0,
SLOT2_IN_STATE = 4,
SLOT3_IN_STATE = 8,
SLOT4_IN_STATE = 12,
SLOT5_IN_STATE = 16,
SLOT6_IN_STATE = 20,
SLOT7_IN_STATE = 24,
SLOT8_IN_STATE = 28,
SLOT1_IN_ERR = 32,
SLOT2_IN_ERR = 36,
SLOT3_IN_ERR = 40,
SLOT4_IN_ERR = 44,
SLOT5_IN_ERR = 48,
SLOT6_IN_ERR = 52,
SLOT7_IN_ERR = 56,
SLOT8_IN_ERR = 60,
FANS_STATUS = 64,
TEMP_STATUS = 65,
VOLT_STATUS = 66,
FAN0_SPEED = 67,
FAN1_SPEED = 69,
FAN2_SPEED = 71,
TEMPERATURE0 = 73,
TEMPERATURE1 = 74,
TEMPERATURE2 = 75,
TEMPERATURE3 = 76,
TEMPERATURE4 = 77,
TEMPERATURE5 = 78
};
};
#endif /* DIOT_CRATE_H */
......@@ -19,6 +19,7 @@
#include <iostream>
#include <QtWidgets/QApplication>
#include <QtWidgets/QDialog>
#include <QBoxLayout>
#include "controller.h"
// Argument values
......@@ -68,9 +69,18 @@ int main( int argc, char **argv ) {
return 0;
}
DiotController controller(&w, address, slots_nr);
DiotHardware hw(address, slots_nr);
QVBoxLayout *mainLayout = new QVBoxLayout();
DiotIOController *controller = new DiotIOController(&w, hw, slots_nr);
mainLayout->addWidget(controller);
DiotDiag *diag = new DiotDiag(&w, hw);
mainLayout->addWidget(diag);
w.setLayout(mainLayout);
w.show();
controller.Start();
hw.Start();
return a.exec();
}
masterfip @ c83c262c
Subproject commit 0e255d8d74a62377ed2da3b112a2a2b48bf3b91d
Subproject commit c83c262c7be22fd58d04bcbddc4d4c8e47771666
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment