From d61337023e487280105823797de722f15201170d Mon Sep 17 00:00:00 2001 From: Niklas Eiling Date: Wed, 13 Dec 2023 15:16:55 +0100 Subject: [PATCH] add draft for i2c drvier implementation Signed-off-by: Niklas Eiling --- fpga/include/villas/fpga/ips/i2c.hpp | 73 ++++++++++++++++++++++++++++ fpga/lib/ips/i2c.cpp | 49 +++++++++++++++++++ fpga/thirdparty/libxil | 2 +- 3 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 fpga/include/villas/fpga/ips/i2c.hpp create mode 100644 fpga/lib/ips/i2c.cpp diff --git a/fpga/include/villas/fpga/ips/i2c.hpp b/fpga/include/villas/fpga/ips/i2c.hpp new file mode 100644 index 000000000..8a9d1e626 --- /dev/null +++ b/fpga/include/villas/fpga/ips/i2c.hpp @@ -0,0 +1,73 @@ +/* I2C driver + * + * Author: Niklas Eiling + * SPDX-FileCopyrightText: 2023 Niklas Eiling + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace villas { +namespace fpga { +namespace ip { + +class I2c : public Node { +public: + friend class I2cFactory; + + virtual ~I2c(); + virtual bool init() override; + bool reset() override; + bool write(std::list &data); + bool read(std::list &data, size_t max_read); + +private: + static constexpr char registerMemory[] = "Reg"; + + XIic xIic; + XIic_Config xConfig; + + std::mutex hwLock; + + bool configDone = false; + + class I2cFactory : NodeFactory { + + public: + virtual std::string getName() const { return "i2c"; } + + virtual std::string getDescription() const { + return "Xilinx's AXI4 iic IP"; + } + + private: + virtual Vlnv getCompatibleVlnv() const { + return Vlnv("xilinx.com:ip:axi_iic:"); + } + + // Create a concrete IP instance + Core *make() const { return new Dma; }; + + protected: + virtual void parse(Core &ip, json_t *json) override; + + virtual void configurePollingMode(Core &ip, PollingMode mode) override { + dynamic_cast(ip).polling = (mode == POLL); + } + }; + +} // namespace ip +} // namespace fpga +} // namespace villas + +#ifndef FMT_LEGACY_OSTREAM_FORMATTER +template <> +class fmt::formatter : public fmt::ostream_formatter {}; +#endif diff --git a/fpga/lib/ips/i2c.cpp b/fpga/lib/ips/i2c.cpp new file mode 100644 index 000000000..2ed35e062 --- /dev/null +++ b/fpga/lib/ips/i2c.cpp @@ -0,0 +1,49 @@ +/* I2C driver + * + * Author: Niklas Eiling + * SPDX-FileCopyrightText: 2023 Niklas Eiling + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +#include +#include + +using namespace villas::fpga::ip; + +I2c::I2c() : Node("i2c") {} + +I2c::~I2c() {} + +bool I2c::init() override {} + +bool I2c::reset() override {} + +bool I2c::write(std::list &data) {} + +bool I2c::read(std::list &data, size_t max_read) {} + +void I2cFactory::parse(Core &ip, json_t *cfg) { + NodeFactory::parse(ip, cfg); + + auto &i2c = dynamic_cast(ip); + + int i2c_frequency = 0; + + json_error_t err; + int ret = json_unpack_ex( + cfg, &err, 0, "{ s: { s?: i, s?: i, s?: i, s?: i, s?: i} }", "parameters", + "c_iic_freq", &i2c_frequency, "c_ten_bit_adr", &i2c.xConfig.Has10BitAddr, + "c_gpo_width", &i2c.xConfig.GpOutWidth, "component_name", + &i2c.xConfig.Name, "c_baseaddr", &i2c.xConfig.BaseAddress); + if (ret != 0) + throw ConfigError(cfg, err, "", "Failed to parse DMA configuration"); + + dma.configDone = true; +} + +static I2cFactory f; diff --git a/fpga/thirdparty/libxil b/fpga/thirdparty/libxil index 60ce084ad..0294cee46 160000 --- a/fpga/thirdparty/libxil +++ b/fpga/thirdparty/libxil @@ -1 +1 @@ -Subproject commit 60ce084ad9f440f807183b6626d7aa56005f25a7 +Subproject commit 0294cee460cb6e4c09881c90b9b255ba9d7a99b3