host: Extend the SPI interface

Introduce 64-bit SPI transaction methods into the common spi_iface API,
default implementation throws an uhd::unsupported_operation exception.
Add explicit 32-bit aliases for the old/existing SPI transactions
methods.

Expose the width-specific operations through the RFNoC Python bindings.
This commit is contained in:
Max Becker 2026-09-15 11:20:05 +02:00 committed by Frank Dietze
parent e6470cf8ce
commit 148c861163
3 changed files with 158 additions and 6 deletions

View File

@ -1,6 +1,6 @@
//
// Copyright 2010-2013 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
// Copyright 2026 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
@ -127,7 +127,7 @@ public:
virtual ~spi_iface(void);
/*!
* Perform a spi transaction.
* Perform a (up to 32-bit) SPI transaction.
* \param which_slave the slave device number
* \param config spi config args
* \param data the bits to write
@ -142,7 +142,44 @@ public:
bool readback) = 0;
/*!
* Read from the SPI bus.
* Perform a 32-bit SPI transaction.
* This method is an explicit-width alias for transact_spi().
* \param which_slave the slave device number
* \param config spi config args
* \param data the bits to write
* \param num_bits how many bits in data
* \param readback true to readback a value
* \return spi data if readback set
*/
uint32_t transact_spi32(int which_slave,
const spi_config_t& config,
uint32_t data,
size_t num_bits,
bool readback)
{
return transact_spi(which_slave, config, data, num_bits, readback);
}
/*!
* Perform a 64-bit SPI transaction.
* Transactions wider than 32 bits are not supported on all devices.
* \param which_slave the slave device number
* \param config spi config args
* \param data the bits to write
* \param num_bits how many bits in data
* \param readback true to readback a value
* \return spi data if readback set
* \throws uhd::not_implemented_error if the device does not support
* transactions wider than 32 bits
*/
virtual uint64_t transact_spi64(int which_slave,
const spi_config_t& config,
uint64_t data,
size_t num_bits,
bool readback);
/*!
* Read (up to 32-bit) from the SPI bus.
* \param which_slave the slave device number
* \param config spi config args
* \param data the bits to write out (be sure to set write bit)
@ -153,7 +190,36 @@ public:
int which_slave, const spi_config_t& config, uint32_t data, size_t num_bits);
/*!
* Write to the SPI bus.
* Read (up to 32-bit) from the SPI bus.
* This method is an explicit-width alias for read_spi().
* \param which_slave the slave device number
* \param config spi config args
* \param data the bits to write out (be sure to set write bit)
* \param num_bits how many bits in data
* \return spi data
*/
uint32_t read_spi32(
int which_slave, const spi_config_t& config, uint32_t data, size_t num_bits)
{
return read_spi(which_slave, config, data, num_bits);
}
/*!
* Read (up to 64-bit) from the SPI bus.
* Transactions wider than 32 bits are not supported on all devices.
* \param which_slave the slave device number
* \param config spi config args
* \param data the bits to write out (be sure to set write bit)
* \param num_bits how many bits in data
* \return spi data
* \throws uhd::not_implemented_error if the device does not support
* transactions wider than 32 bits
*/
virtual uint64_t read_spi64(
int which_slave, const spi_config_t& config, uint64_t data, size_t num_bits);
/*!
* Write (up to 32-bit) to the SPI bus.
* \param which_slave the slave device number
* \param config spi config args
* \param data the bits to write
@ -161,6 +227,33 @@ public:
*/
virtual void write_spi(
int which_slave, const spi_config_t& config, uint32_t data, size_t num_bits);
/*!
* Write (up to 32-bit) to the SPI bus.
* This method is an explicit-width alias for write_spi().
* \param which_slave the slave device number
* \param config spi config args
* \param data the bits to write
* \param num_bits how many bits in data
*/
void write_spi32(
int which_slave, const spi_config_t& config, uint32_t data, size_t num_bits)
{
write_spi(which_slave, config, data, num_bits);
}
/*!
* Write (up to 64-bit) to the SPI bus.
* Transactions wider than 32 bits are not supported on all devices.
* \param which_slave the slave device number
* \param config spi config args
* \param data the bits to write
* \param num_bits how many bits in data
* \throws uhd::not_implemented_error if the device does not support
* transactions wider than 32 bits
*/
virtual void write_spi64(
int which_slave, const spi_config_t& config, uint64_t data, size_t num_bits);
};
/*!

View File

@ -1,5 +1,5 @@
//
// Copyright 2019 Ettus Research, a National Instruments Brand
// Copyright 2026 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
@ -154,17 +154,55 @@ void export_rfnoc(py::module& m)
py::arg("data"),
py::arg("num_bits"),
py::arg("readback"))
.def("transact_spi32",
&uhd::spi_iface::transact_spi32,
py::arg("which_slave"),
py::arg("config"),
py::arg("data"),
py::arg("num_bits"),
py::arg("readback"))
.def("transact_spi64",
&uhd::spi_iface::transact_spi64,
py::arg("which_slave"),
py::arg("config"),
py::arg("data"),
py::arg("num_bits"),
py::arg("readback"))
.def("read_spi",
&uhd::spi_iface::read_spi,
py::arg("which_slave"),
py::arg("config"),
py::arg("data"),
py::arg("num_bits"))
.def("read_spi32",
&uhd::spi_iface::read_spi32,
py::arg("which_slave"),
py::arg("config"),
py::arg("data"),
py::arg("num_bits"))
.def("read_spi64",
&uhd::spi_iface::read_spi64,
py::arg("which_slave"),
py::arg("config"),
py::arg("data"),
py::arg("num_bits"))
.def("write_spi",
&uhd::spi_iface::write_spi,
py::arg("which_slave"),
py::arg("config"),
py::arg("data"),
py::arg("num_bits"))
.def("write_spi32",
&uhd::spi_iface::write_spi32,
py::arg("which_slave"),
py::arg("config"),
py::arg("data"),
py::arg("num_bits"))
.def("write_spi64",
&uhd::spi_iface::write_spi64,
py::arg("which_slave"),
py::arg("config"),
py::arg("data"),
py::arg("num_bits"));
py::class_<uhd::features::spi_getter_iface,

View File

@ -1,11 +1,13 @@
//
// Copyright 2011-2013 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
// Copyright 2026 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#include <uhd/exception.hpp>
#include <uhd/types/serial.hpp>
#include <uhd/utils/log.hpp>
#include <uhdlib/utils/narrow.hpp>
#include <chrono>
#include <thread>
@ -118,3 +120,22 @@ void spi_iface::write_spi(
{
transact_spi(which_slave, config, data, num_bits, false);
}
uint64_t spi_iface::transact_spi64(int, const spi_config_t&, uint64_t, size_t, bool)
{
UHD_LOG_THROW(uhd::not_implemented_error,
"SPI",
"64-bit SPI transactions are only supported on x4xx devices");
}
uint64_t spi_iface::read_spi64(
int which_slave, const spi_config_t& config, uint64_t data, size_t num_bits)
{
return transact_spi64(which_slave, config, data, num_bits, true);
}
void spi_iface::write_spi64(
int which_slave, const spi_config_t& config, uint64_t data, size_t num_bits)
{
transact_spi64(which_slave, config, data, num_bits, false);
}