1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

automatically configure and test Dino based on hwdef json

this currently requires manually adding the mapping of Dinos to i2c
buses in the fpga json.

Signed-off-by: Niklas Eiling <niklas.eiling@eonerc.rwth-aachen.de>
This commit is contained in:
Niklas Eiling 2024-01-09 17:07:21 +01:00 committed by Niklas Eiling
parent b5682290c2
commit 8b95182b08
3 changed files with 90 additions and 9 deletions

View file

@ -1014,6 +1014,7 @@
},
"dino_dinoif_dac_0": {
"vlnv": "xilinx.com:module_ref:dinoif_dac:1.0",
"i2c_channel": 1,
"parameters": {
"component_name": "design_1_dinoif_dac_0_0",
"edk_iptype": "PERIPHERAL"
@ -1028,6 +1029,7 @@
},
"dino_dinoif_fast_0": {
"vlnv": "xilinx.com:module_ref:dinoif_fast:1.0",
"i2c_channel": 0,
"parameters": {
"component_name": "design_1_dinoif_fast_0_0",
"edk_iptype": "PERIPHERAL"

View file

@ -18,6 +18,7 @@ namespace ip {
class Dino : public Node {
public:
friend class DinoFactory;
union IoextPorts {
struct __attribute__((packed)) {
bool clk_dir : 1;
@ -52,6 +53,7 @@ public:
Dino();
virtual ~Dino();
virtual bool init() override;
void setI2c(std::shared_ptr<I2c> i2cdev, uint8_t i2c_channel) {
this->i2cdev = i2cdev;
this->i2c_channel = i2c_channel;
@ -75,6 +77,7 @@ public:
protected:
std::shared_ptr<I2c> i2cdev;
uint8_t i2c_channel;
bool configDone;
IoextPorts getIoextDir();
IoextPorts getIoextOut();
@ -98,6 +101,41 @@ public:
Gain getGain();
};
class DinoFactory : NodeFactory {
public:
virtual std::string getDescription() const { return "Dino Analog I/O"; }
protected:
virtual void parse(Core &ip, json_t *json) override;
};
class DinoAdcFactory : DinoFactory {
public:
virtual std::string getName() const { return "dinoAdc"; }
private:
virtual Vlnv getCompatibleVlnv() const {
return Vlnv("xilinx.com:module_ref:dinoif_fast:");
}
Core *make() const { return new DinoAdc; };
};
class DinoDacFactory : DinoFactory {
public:
virtual std::string getName() const { return "dinoDac"; }
private:
virtual Vlnv getCompatibleVlnv() const {
return Vlnv("xilinx.com:module_ref:dinoif_dac:");
}
Core *make() const { return new DinoDac; };
};
} // namespace ip
} // namespace fpga
} // namespace villas
#ifndef FMT_LEGACY_OSTREAM_FORMATTER
template <>
class fmt::formatter<villas::fpga::ip::Dino> : public fmt::ostream_formatter {};
#endif

View file

@ -9,14 +9,35 @@
#include <villas/utils.hpp>
#include <villas/fpga/card.hpp>
#include <villas/fpga/ips/dino.hpp>
using namespace villas::fpga::ip;
Dino::Dino() : Node(), i2cdev(nullptr), i2c_channel(0) {}
Dino::Dino() : Node(), i2cdev(nullptr), i2c_channel(0), configDone(false) {}
Dino::~Dino() {}
bool Dino::init() {
if (!configDone) {
logger->error("Dino configuration not done yet");
throw RuntimeError("Dino configuration not done yet");
}
if (i2cdev == nullptr) {
i2cdev = std::dynamic_pointer_cast<fpga::ip::I2c>(
card->lookupIp(fpga::Vlnv("xilinx.com:ip:axi_iic:")));
if (i2cdev == nullptr) {
logger->error("No I2C found on FPGA");
throw RuntimeError(
"Dino requires and I2C device but none was found on FPGA");
} else {
logger->debug("Found I2C on FPGA");
}
}
configureHardware();
return true;
}
void Dino::setIoextDir(IoextPorts ports) {
if (i2cdev == nullptr) {
throw RuntimeError("I2C device not set");
@ -80,6 +101,10 @@ DinoAdc::DinoAdc() : Dino() {}
DinoAdc::~DinoAdc() {}
void DinoAdc::configureHardware() {
if (!configDone) {
logger->error("ADC configuration not done yet");
throw RuntimeError("ADC configuration not done yet");
}
if (i2cdev == nullptr) {
throw RuntimeError("I2C device not set");
}
@ -117,6 +142,10 @@ DinoDac::DinoDac() : Dino() {}
DinoDac::~DinoDac() {}
void DinoDac::configureHardware() {
if (!configDone) {
logger->error("DAC configuration not done yet");
throw RuntimeError("DAC configuration not done yet");
}
if (i2cdev == nullptr) {
throw RuntimeError("I2C device not set");
}
@ -169,12 +198,24 @@ Dino::Gain DinoDac::getGain() {
return ret;
}
static char n_adc[] = "DINO ADC";
static char d_adc[] = "DINO analog to digital converter";
static char v_adc[] = "xilinx.com:module_ref:dinoif_fast:";
static NodePlugin<DinoAdc, n_adc, d_adc, v_adc> f_adc;
void DinoFactory::parse(Core &ip, json_t *cfg) {
NodeFactory::parse(ip, cfg);
static char n_dac[] = "DINO DAC";
static char d_dac[] = "DINO digital to analog converter";
static char v_dac[] = "xilinx.com:module_ref:dinoif_dac:";
static NodePlugin<DinoDac, n_dac, d_dac, v_dac> f_dac;
auto &dino = dynamic_cast<Dino &>(ip);
json_error_t err;
int i2c_channel;
int ret =
json_unpack_ex(cfg, &err, 0, "{ s: i }", "i2c_channel", &i2c_channel);
if (ret != 0) {
throw ConfigError(cfg, err, "", "Failed to parse Dino configuration");
}
if (i2c_channel < 0 || i2c_channel >= 8) {
throw ConfigError(cfg, err, "", "Invalid I2C channel");
}
dino.i2c_channel = static_cast<uint8_t>(i2c_channel);
dino.configDone = true;
}
static DinoAdcFactory fAdc;
static DinoDacFactory fDac;