Skip to content

Instantly share code, notes, and snippets.

@Bktero
Last active July 27, 2018 10:44
Show Gist options
  • Select an option

  • Save Bktero/5d4b3ef4d020e47e8aabfb7b7aad1429 to your computer and use it in GitHub Desktop.

Select an option

Save Bktero/5d4b3ef4d020e47e8aabfb7b7aad1429 to your computer and use it in GitHub Desktop.
[C++17] Example of std::variant to execute various type of request on a SPI bus
#include <cassert>
#include <cstdint>
#include <variant>
struct ReadRequest {
ReadRequest(std::uint8_t* data, std::size_t length) :
data(data),
length(length) {
assert(data != nullptr);
}
std::uint8_t* const data;
const std::size_t length;
};
struct WriteRequest {
WriteRequest(const std::uint8_t* data, std::size_t length) :
data(data),
length(length) {
assert(data != nullptr);
}
const std::uint8_t* const data;
const std::size_t length;
};
struct WriteReadRequest {
WriteReadRequest(const std::uint8_t* writeData, std::size_t writeLength,
std::uint8_t* readData, std::size_t readLength) :
readData(readData),
readLength(readLength),
writeData(writeData),
writeLength(writeLength) {
assert(readData != nullptr);
assert(writeData != nullptr);
}
std::uint8_t* const readData;
const std::size_t readLength;
const std::uint8_t* const writeData;
const std::size_t writeLength;
};
struct DoubleWriteRequest {
DoubleWriteRequest(const std::uint8_t* firstData, std::size_t firstLength,
const std::uint8_t* secondData, std::size_t secondLength) :
firstData(firstData),
firstLength(firstLength),
secondData(secondData),
secondLength(secondLength) {
assert(firstData != nullptr);
assert(secondData != nullptr);
}
const std::uint8_t* const firstData;
const std::size_t firstLength;
const std::uint8_t* const secondData;
const std::size_t secondLength;
};
using Request =std::variant<ReadRequest,
WriteRequest,
WriteReadRequest,
DoubleWriteRequest>;
//---------------------------------------------------------------------------------
extern "C" {
void spi_driver_read(std::uint8_t* data, std::size_t length);
void spi_driver_write(const std::uint8_t* data, std::size_t length);
}
class SpiBus {
public:
void execute(const Request& request) {
RequestProcessor requestProcessor;
std::visit(requestProcessor, request);
}
private:
class RequestProcessor {
public:
void operator()(const ReadRequest& request) {
spi_driver_read(request.data, request.length);
}
void operator()(const WriteRequest& request) {
spi_driver_write(request.data, request.length);
}
void operator()(const WriteReadRequest& request) {
spi_driver_write(request.writeData, request.writeLength);
spi_driver_read(request.readData, request.readLength);
}
void operator()(const DoubleWriteRequest& request) {
spi_driver_write(request.firstData, request.firstLength);
spi_driver_write(request.secondData, request.secondLength);
}
};
};
//--------------------------------------------------------------------------------
#include <array>
int main() {
SpiBus bus;
std::array<std::uint8_t, 15> buffer;
ReadRequest rr{buffer.data(), buffer.size()};
bus.execute(rr);
//ReadRequest bad_rr{nullptr, 42}; // triggers assert()
WriteRequest wr{buffer.data(), buffer.size()};
bus.execute(wr);
WriteReadRequest wrr{buffer.data(), 2, buffer.data(), 13};
bus.execute(wrr);
DoubleWriteRequest dwr{buffer.data(), 10, buffer.data(), 5};
bus.execute(dwr);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment