peary/device/PearyDevice.hpp

Peary Device Class. More…

Namespaces

Name
peary
peary::device

Classes

Name
class peary::device::PearyDevice Peary Device class definition.

Defines

Name
MEM_PATH

Detailed Description

Peary Device Class.

Copyright: Copyright (c) 2016-2025 CERN and the Peary Caribou authors. This software is distributed under the terms of the LGPL-3.0-only License, copied verbatim in the file “LICENSE.md”. SPDX-License-Identifier: LGPL-3.0-only

Macros Documentation

define MEM_PATH

  #define MEM_PATH "/dev/mem"
  

Source code

  
#pragma once

#include <any>
#include <cstdint>
#include <optional>
#include <string>
#include <string_view>
#include <tuple>
#include <vector>

#include "peary/config/configuration.hpp"
#include "peary/hal/Resources.hpp"
#include "peary/interfaces/AXI4Lite/axi4lite.hpp"
#include "peary/utils/constants.hpp"
#include "peary/utils/datatypes.hpp"
#include "peary/utils/dictionary.hpp"

#include "Device.hpp"

#define MEM_PATH "/dev/mem"

namespace peary::device {

    class Board;

    template <typename B, typename SCI, typename DRI = SCI> class PearyDevice : public Device {

    public:
        template <typename... ArgsSCI>
        PearyDevice(std::string_view name, const config::Configuration& config, ArgsSCI&&... sciArgs);

        template <typename... ArgsSCI, typename... ArgsDRI>
        PearyDevice(std::string_view name,
                    const config::Configuration config,
                    std::tuple<ArgsSCI...> sciArgs,
                    std::tuple<ArgsDRI...> driArgs);

        std::string getFirmwareVersion() override;

        std::string getType() override;

        uint8_t getBoardID();

        uint16_t getChipID() { return 0; };

        std::string getDeviceName();

        void powerOn() override;

        virtual void powerUp() = 0;

        void powerOff() override;

        virtual void powerDown() = 0;

        void daqStart() override = 0;

        void daqStop() override = 0;

        void configure() override;

        void setRegister(const std::string& name, uintptr_t value) override;

        virtual void setSpecialRegister(const std::string&, uintptr_t) {};

        virtual uintptr_t getSpecialRegister(const std::string&) { return 0; };

        uintptr_t getRegister(const std::string& name) override;

        std::vector<std::pair<std::string, uintptr_t>> getRegisters() override;

        bool hasRegister(const std::string& name) const override;

        void reset() override;

        void setVoltage(const std::string& name, double voltage) override;

        void setCurrentLimit(const std::string& name, double current_limit) override;

        void setCurrent(const std::string& name, double current, utils::Polarity polarity) override;

        void switchOn(const std::string& name) override { return switch_resource(name, true); };

        void switchOff(const std::string& name) override { return switch_resource(name, false); };

        double getVoltage(const std::string& name) override;

        double getCurrent(const std::string& name) override;

        double getPower(const std::string& name) override;

        bool getAlertStatus(const std::string& name);

        double getTemperature(const std::string& name);

        void configureClock(const std::string& name, const std::any& config) override;

        void disableClock(const std::string& name) override;

        bool isClockLocked(const std::string& name) override;

        void setClockFrequency(const std::string& name, uint64_t frequency) override;

        std::vector<std::string> listMemories() override;

        std::vector<std::string> listRegisters() override;

        std::vector<std::pair<std::string, std::string>> listResources() override;

        std::optional<utils::pearyRawData> getRawData() override;

        std::optional<utils::pearyRawDataVector> getRawData(const unsigned int noFrames) override;

        std::optional<utils::pearydata> getData() override;

        std::optional<utils::pearydataVector> getData(const unsigned int noFrames) override;

        void setMemory(const std::string& name, size_t offset, uintptr_t value) override;

        void setMemory(const std::string& name, uintptr_t value) override;

        template <typename D = uintptr_t> D getMemoryDefault(const std::string& name);

        template <typename D = uintptr_t> D getMemory(const std::string& name, size_t offset);

        uintptr_t getMemory(const std::string& name, size_t offset) override { return getMemory<uintptr_t>(name, offset); }

        template <typename D = uintptr_t> D getMemory(const std::string& name);

        uintptr_t getMemory(const std::string& name) override { return getMemory<uintptr_t>(name); }

        std::vector<std::pair<std::string, uintptr_t>> getMemories() override;

        bool hasMemory(const std::string& name) const override;

    protected:
        void register_resource(const std::string& name, B::R res);

        void register_memory(const std::string& name,
                             utils::memory_map mem,
                             utils::register_t<std::uintptr_t, std::uintptr_t> reg);

        void register_memory(
            const std::vector<
                std::pair<std::string, std::pair<utils::memory_map, utils::register_t<std::uintptr_t, std::uintptr_t>>>>
                elements);

        void process_register_write(utils::register_t<typename SCI::reg_t, typename SCI::data_t> reg, uintptr_t value);

        uintptr_t process_register_read(utils::register_t<typename SCI::reg_t, typename SCI::data_t> reg);

        std::shared_ptr<B> _board;

        config::Configuration _config;

        utils::dictionary<utils::register_t<typename SCI::reg_t, typename SCI::data_t>> _registers;

        std::map<std::string, typename SCI::data_t> _register_cache;

        typename SCI::data_t send(const typename SCI::data_t& data);

        typename SCI::vector_t send(const std::vector<typename SCI::data_t>& data);

        std::pair<typename SCI::reg_t, typename SCI::data_t>
        send(const std::pair<typename SCI::reg_t, typename SCI::data_t>& data);

        typename SCI::vector_t send(const typename SCI::reg_t& reg, const std::vector<typename SCI::data_t>& data);

        std::vector<std::pair<typename SCI::reg_t, typename SCI::data_t>>
        send(const std::vector<std::pair<typename SCI::reg_t, typename SCI::data_t>>& data);

        typename SCI::vector_t receive(const typename SCI::reg_t reg, const unsigned int length = 1);

        typename DRI::vector_t receiveData(const unsigned int length = 1);

        typename DRI::vector_t receiveData(const typename DRI::reg_t reg, const unsigned int length = 1);

    private:
        template <typename reg_type, typename data_type>
        data_type obey_mask_write(utils::register_t<reg_type, data_type> reg, data_type regval, data_type regcurrval) const;

        template <typename reg_type, typename data_type>
        data_type obey_mask_read(utils::register_t<reg_type, data_type> reg, data_type regval) const;

    private:
        /* Periphery dictionary to access board components */
        utils::dictionary<hal::Resource> _periphery;

        /* Memory page dictionary to access FPGA registers */
        utils::dictionary<std::pair<utils::memory_map, utils::register_t<std::uintptr_t, std::uintptr_t>>> _axi4lite_memory;
        std::map<utils::memory_map, interface::AXI4LiteEndpoint> _axi4lite_memory_endpoints;

        /* Slow control interface configuration */
        SCI _iface_slow_control;

        /* Data Readout interface configuration */
        DRI _iface_data_readout;

        /* State indicating powering of the device */
        bool _is_powered;

        /* State indicating the configuration of the device */
        bool _is_configured;

        void switch_resource(const std::string& name, bool enable);

    }; // class PearyDevice

} // namespace peary::device

#include "PearyDevice.tcc"
  

Updated on 2026-01-30 at 22:01:05 +0100