FluxSand 1.0
FluxSand - Interactive Digital Hourglass
Loading...
Searching...
No Matches
bsp_spi.hpp
1#pragma once
2
3#include <fcntl.h>
4#include <linux/spi/spidev.h>
5#include <sys/ioctl.h>
6#include <unistd.h>
7
8#include <array>
9#include <cassert>
10#include <cstdint>
11#include <cstring>
12#include <stdexcept>
13#include <string>
14
15#include "bsp_gpio.hpp"
16
20class SpiDevice {
21 public:
29 SpiDevice(const std::string& device, uint32_t speed, uint8_t mode)
30 : fd_(open(device.c_str(), O_RDWR)), speed_(speed) {
31 assert(!device.empty()); /* Ensure device string is valid */
32
33 if (fd_ < 0) {
34 std::perror("Failed to open SPI device");
35 }
36
37 if (ioctl(fd_, SPI_IOC_WR_MODE, &mode) < 0 ||
38 ioctl(fd_, SPI_IOC_WR_MAX_SPEED_HZ, &speed_) < 0) {
39 close(fd_);
40 std::perror("Failed to configure SPI device");
41 }
42 }
43
46 if (fd_ >= 0) {
47 close(fd_);
48 }
49 }
50
58 uint8_t ReadRegister(Gpio* cs, uint8_t reg) {
59 assert(cs); /* Ensure GPIO object is valid */
60
61 std::array<uint8_t, 2> tx_buf = {{static_cast<uint8_t>(reg | 0x80), 0}};
62 std::array<uint8_t, 2> rx_buf = {{0, 0}};
63 struct spi_ioc_transfer transfer{};
64 transfer.tx_buf = reinterpret_cast<uint64_t>(tx_buf.data());
65 transfer.rx_buf = reinterpret_cast<uint64_t>(rx_buf.data());
66 transfer.len = tx_buf.size();
67 transfer.speed_hz = speed_;
68 transfer.bits_per_word = 8;
69
70 cs->Write(0);
71 usleep(10);
72 if (ioctl(fd_, SPI_IOC_MESSAGE(1), &transfer) < 0) {
73 cs->Write(1);
74 std::perror("SPI read failed");
75 }
76 cs->Write(1);
77
78 return rx_buf[1];
79 }
80
88 void WriteRegister(Gpio* cs, uint8_t reg, uint8_t value) {
89 assert(cs); /* Ensure GPIO object is valid */
90
91 std::array<uint8_t, 2> tx_buf = {{reg, value}};
92 struct spi_ioc_transfer transfer{};
93 transfer.tx_buf = reinterpret_cast<uint64_t>(tx_buf.data());
94 transfer.len = tx_buf.size();
95 transfer.speed_hz = speed_;
96 transfer.bits_per_word = 8;
97
98 cs->Write(0);
99 usleep(10);
100 if (ioctl(fd_, SPI_IOC_MESSAGE(1), &transfer) < 0) {
101 cs->Write(1);
102 std::perror("SPI write failed");
103 }
104 cs->Write(1);
105 }
106
107 void ReadRegisters(Gpio* cs, uint8_t reg, uint8_t* buffer, size_t length) {
108 assert(cs);
109 assert(buffer);
110
111 std::vector<uint8_t> tx_buf(length + 1, 0);
112 std::vector<uint8_t> rx_buf(length + 1, 0);
113 tx_buf[0] = reg | 0x80;
114
115 struct spi_ioc_transfer transfer{};
116 transfer.tx_buf = reinterpret_cast<uint64_t>(tx_buf.data());
117 transfer.rx_buf = reinterpret_cast<uint64_t>(rx_buf.data());
118 transfer.len = tx_buf.size();
119 transfer.speed_hz = speed_;
120 transfer.bits_per_word = 8;
121
122 cs->Write(0);
123 usleep(10);
124 if (ioctl(fd_, SPI_IOC_MESSAGE(1), &transfer) < 0) {
125 cs->Write(1);
126 std::perror("SPI multiple read failed");
127 }
128 cs->Write(1);
129
130 std::memcpy(buffer, rx_buf.data() + 1, length);
131 }
132
133 int Fd() const { return fd_; }
134
135 uint32_t Speed() const { return speed_; }
136
137 private:
138 int fd_; /* SPI file descriptor */
139 uint32_t speed_; /* Transfer speed in Hz */
140};
void Write(int value)
Definition bsp_gpio.hpp:82
uint8_t ReadRegister(Gpio *cs, uint8_t reg)
Definition bsp_spi.hpp:58
void WriteRegister(Gpio *cs, uint8_t reg, uint8_t value)
Definition bsp_spi.hpp:88
SpiDevice(const std::string &device, uint32_t speed, uint8_t mode)
Definition bsp_spi.hpp:29