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:
parent
b5682290c2
commit
8b95182b08
3 changed files with 90 additions and 9 deletions
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue