peary/utils/datatypes.hpp

Peary Data Types. More…

Namespaces

Name
peary
peary::utils

Classes

Name
class peary::utils::pixel Basic pixel class.
struct peary::utils::pearyRawDataWord Represents a raw data word.
class peary::utils::register_t Class to represent a register configuration.
struct peary::utils::SI5345_REG_T Struct to represent a register in the SI5345.
class peary::utils::memory_map Class to represent a memory map.

Detailed Description

Peary Data Types.

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

Source code

  
#pragma once

#include <cstdint>
#include <iostream>
#include <limits>
#include <map>
#include <memory>
#include <tuple>
#include <vector>

#include <strings.h>
#include <sys/mman.h>

namespace peary::utils {

    class pixel {
    public:
        pixel() = default;

        virtual ~pixel() = default;

        pixel(const pixel&) = default;
        pixel& operator=(const pixel&) = default;

        pixel(pixel&&) = default;

        pixel& operator=(pixel&&) = default;

        friend std::ostream& operator<<(std::ostream& out, const pixel& px) {
            px.print(out);
            return out;
        }

    protected:
        virtual void print(std::ostream&) const {};
    };

    using pearydata = std::map<std::pair<uint16_t, uint16_t>, std::unique_ptr<pixel>>;

    using pearydataVector = std::vector<pearydata>;

    struct pearyRawDataWord {

        uintptr_t word;

        pearyRawDataWord() = default;

        pearyRawDataWord(uintptr_t w) noexcept : word(w) {};

        operator uintptr_t() const { return word; }
    };

    using pearyRawData = std::vector<pearyRawDataWord>;

    using pearyRawDataVector = std::vector<pearyRawData>;

    template <typename REG_T = uint8_t, typename MASK_T = REG_T> class register_t {
    public:
        register_t() = default;

        explicit register_t(REG_T address) : _address(address), _mask(std::numeric_limits<MASK_T>::max()) {};

        register_t(REG_T address, bool readable, bool writable)
            : _address(address), _mask(std::numeric_limits<MASK_T>::max()), _readable(readable), _writable(writable) {};

        explicit register_t(REG_T address, MASK_T mask) : _address(address), _mask(mask) {};

        explicit register_t(REG_T address, MASK_T mask, bool readable, bool writable, bool special = false)
            : _address(address), _mask(mask), _special(special), _readable(readable), _writable(writable) {};

        explicit register_t(
            REG_T address, MASK_T mask, MASK_T value, bool readable = true, bool writable = true, bool special = false)
            : _address(address), _mask(mask), _default(value), _has_default(true), _special(special), _readable(readable),
              _writable(writable) {};

        REG_T address() const { return _address; };

        MASK_T mask() const { return _mask; };

        MASK_T value() const { return _default; };

        bool hasValue() const { return _has_default; };

        bool special() const { return _special; };

        bool writable() const { return _writable; }

        bool readable() const { return _readable; }

        MASK_T shift() const {
            if(_mask > 0) {
                return static_cast<MASK_T>(ffsl(static_cast<int64_t>(_mask)) - 1);
            } else {
                return 0;
            }
        };

        template <typename T1, typename T2> friend std::ostream& operator<<(std::ostream& os, const register_t<T1, T2>& rg);

    private:
        REG_T _address {};
        MASK_T _mask {};
        MASK_T _default {};
        bool _has_default {false};
        bool _special {false};
        bool _readable {true};
        bool _writable {true};
    };

    template <typename T1, typename T2> std::ostream& operator<<(std::ostream& os, const register_t<T1, T2>& rg) {
        os << to_hex_string(rg._address) << " (" << to_bit_string(rg._mask) << ")";
        if(rg._writable && rg._readable) {
            os << " RW";
        } else if(!rg._writable && rg._readable) {
            os << " RO";
        } else if(rg._writable && !rg._readable) {
            os << " WO";
        }
        return os;
    }

    struct SI5345_REG_T {
        uint16_t address; /* 16-bit register address */
        uint8_t value;    /* 8-bit register data */
    };

    enum class Polarity { LOW = 0, HIGH = 1 };

    enum class Direction { OUT = 0, IN = 1 };

    class memory_map {
    public:
        memory_map(std::uintptr_t base_address, std::size_t size, int flags = PROT_READ)
            : _base_address(base_address), _size(size), _flags(flags) {};

        std::uintptr_t getBaseAddress() const { return _base_address; }

        std::size_t getSize() const { return _size; }

        int getFlags() const { return _flags; }

        bool writable() const { return (_flags & PROT_WRITE) != 0; }

        bool operator<(const memory_map& other) const {
            if(_base_address == other.getBaseAddress()) {
                if(_size == other.getSize()) {
                    return _flags < other.getFlags();
                }
                return _size < other.getSize();
            }
            return _base_address < other.getBaseAddress();
        }

    private:
        std::uintptr_t _base_address;
        std::size_t _size;
        int _flags;
    };
} // namespace peary::utils
  

Updated on 2025-11-14 at 11:31:23 +0100