peary/interfaces/SPI_BUS/spi_bus.hpp

Peary SPI Bus Interface. More…

Namespaces

Name
peary
peary::interface

Classes

Name
class peary::interface::iface_spi_bus_config Configuration class for SPI bus interface.
class peary::interface::iface_spi_bus

Detailed Description

Peary SPI Bus Interface.

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 "peary/interfaces/SPI/spi.hpp"

namespace peary::interface {

    /* SPI bus interface class
     * In this implementation 2 type of the SPI frames are considered: read and write frame.
     * The type of the frame is distinguished by the most significant bit of the SPI transaction on MOSI lines.
     * The polairity of this bit is distinguished by write strobe (ws) parameter of the class constructor.
     * The frame type bit in the SPI frame is followed then by address of the register to be accessed and data.
     * The maximum width of SPI frame supported by the class is limited by the width of uintmax_t type.
     *
     * E.g. addressBits = 8, dataBits = 8, ws = 1
     *
     * Read operation:
     *
     *         1b    8bit     8bit
     * MOSI | !ws |  ADDR  |    -  |
     * MISO | -   |    -   |  DATA |
     *
     * Write operation:
     *
     *         1b    8bit     8bit
     * MOSI | ws  |  ADDR  |  DATA  |
     * MISO |   - |    -   |   -    |
     *
     * As most of the SPI drivers support properly on 8 bits_per_word size, the actual SPI transaction has length
     * which is multiple of 8-bits. alignMSB defines whether the read/write operation is aligned to MSB or LSB.
     * for the previous example, alignMSB=1 would correspond to the actual SPI transaction:
     *
     * Read/write operation:
     *         1b    8bit     8bit        7bit
     * MOSI | ws  |  ADDR  |  (DATA)  | PADDING
     * MISO |   - |    -   |  (DATA)  | PADDING
     *
     * While alignMSB=0 would produce:
     *
     * Read/write operation:
     *         7b      1b    8bit      8bit
     * MOSI PADDING | ws  |  ADDR  |  (DATA)  |
     * MISO PADDING |   - |    -   |  (DATA)  |
     *
     */

    class iface_spi_bus_config : public InterfaceConfiguration {
    public:
        iface_spi_bus_config(std::string const& devpath,
                             const uint8_t addressBits,
                             const uint8_t dataBits,
                             const bool ws,
                             const bool alignMSB);

        uint8_t _addressBits;
        uint8_t _dataBits;
        const bool _ws;
        const bool _alignMSB;

        using InterfaceConfiguration::operator<;
        virtual bool operator<(const iface_spi_bus_config& rhs) const;
    };

    class iface_spi_bus : public iface_spi<> {

    public:
        typedef iface_spi_bus_config configuration_type;

    protected:
        const uint8_t _addressBits;
        const uint8_t _dataBits;

        // Masks constants used by the class
        const spi_reg_t _addressMask;

        const spi_t _dataMask;

        // Minimum length of the actual SPI frame aligned to 8bits, which can accommodate data
        const size_t _length;

        const bool _ws;

        const bool _alignMSB;

        explicit iface_spi_bus(const configuration_type& config);

        ~iface_spi_bus() override = default;

        GENERATE_FRIENDS()

    public:
        std::pair<spi_reg_t, spi_t> write(const std::pair<spi_reg_t, spi_t>& data) override;

        std::vector<std::pair<spi_reg_t, spi_t>> write(const std::vector<std::pair<spi_reg_t, spi_t>>& data) override;

        dataVector_type read(const spi_reg_t& reg, const unsigned int length) override;

        std::pair<spi_reg_t, spi_t> access(const bool rw, const std::pair<spi_reg_t, spi_t>& data);

        iface_spi_bus() = delete;

        friend iface_spi_bus& InterfaceManager::getInterface<iface_spi_bus>(const configuration_type&);

        friend void InterfaceManager::deleteInterface<iface_spi_bus>(iface_spi_bus*);

    }; // class iface_spi_bus

} // namespace peary::interface
  

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