libyggdrasil  v1.0.0
spi.hpp
Go to the documentation of this file.
1  /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * _____.___. .___ .__.__ *
3  * \__ | | ____ ____ __| _/___________ _____|__| | *
4  * / | |/ ___\ / ___\ / __ |\_ __ \__ \ / ___/ | | *
5  * \____ / /_/ > /_/ > /_/ | | | \// __ \_\___ \| | |__ *
6  * / ______\___ /\___ /\____ | |__| (____ /____ >__|____/ *
7  * \/ /_____//_____/ \/ \/ \/ *
8  * - Asgard - *
9  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
10  * This software can be used by students and other personal of the *
11  * Bern University of Applied Sciences under the terms of the MIT *
12  * license. *
13  * For other persons this software is under the terms of the GNU *
14  * General Public License version 2. *
15  * *
16  * Copyright © 2021, Bern University of Applied Sciences. *
17  * All rights reserved. *
18  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
26 #pragma once
27 
29 
30 #include <string>
31 #include <string_view>
32 #include <array>
33 
34 #include <fcntl.h>
35 #include <sys/ioctl.h>
36 #include <linux/types.h>
37 
38 namespace bsp::asg::drv {
39 
46  template<auto Context>
47  struct SPI {
48 
54  static bool init() {
55  SPI::s_device = open(("/dev/spidev" + std::to_string(Context[0]) + "." + std::to_string(Context[1])).c_str(), O_RDWR);
56  if (SPI::s_device == -1)
57  return false;
58 
59  u8 mode = 0;
60  u8 bitsPerWord = 8;
61  u32 speed = 1'000'000;
62 
63 
64  if (ioctl(SPI::s_device, SPI_IOC_WR_MODE, &mode) < 0)
65  return false;
66 
67  if (ioctl(SPI::s_device, SPI_IOC_WR_BITS_PER_WORD, &bitsPerWord) < 0)
68  return false;
69 
70  if (ioctl(SPI::s_device, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0)
71  return false;
72 
73  SPI::s_transfer.bits_per_word = bitsPerWord;
74  SPI::s_transfer.cs_change = 0;
75  SPI::s_transfer.delay_usecs = 0;
76  SPI::s_transfer.speed_hz = speed;
77 
78  return true;
79  }
80 
86  static bool deinit() {
87  close(SPI::s_device);
88  return true;
89  }
90 
97  template<size_t N>
98  static void read(std::array<u8, N> &data) {
99  std::array<u8, N> dummyData;
100 
101  SPI::s_transfer.tx_buf = reinterpret_cast<u64>(dummyData.data());
102  SPI::s_transfer.rx_buf = reinterpret_cast<u64>(data.data());
103  SPI::s_transfer.len = data.size();
104 
105  ioctl(SPI::s_device, SPI_IOC_MESSAGE(1), &SPI::s_transfer);
106  }
107 
114  template<size_t N>
115  static void write(const std::array<u8, N> &data) {
116  std::array<u8, N> dummyData;
117  SPI::s_transfer.tx_buf = reinterpret_cast<u64>(data.data());
118  SPI::s_transfer.tx_buf = reinterpret_cast<u64>(dummyData.data());
119  SPI::s_transfer.len = data.size();
120 
121  ioctl(SPI::s_device, SPI_IOC_MESSAGE(1), &SPI::s_transfer);
122  }
123 
130  static void setMode(bsp::drv::SPIMode mode) {
131  u8 value = 0;
132  if (ioctl(SPI::s_device, SPI_IOC_RD_MODE, &value) < 0)
133  return;
134 
135  value &= ~SPI_MODE_3;
136 
137  switch (mode) {
138  case bsp::drv::SPIMode::_0:
139  value |= SPI_MODE_0;
140  break;
141  case bsp::drv::SPIMode::_1:
142  value |= SPI_MODE_1;
143  break;
144  case bsp::drv::SPIMode::_2:
145  value |= SPI_MODE_2;
146  break;
148  value |= SPI_MODE_3;
149  break;
150  }
151 
152  ioctl(SPI::s_device, SPI_IOC_WR_MODE, &value);
153  }
154 
155  private:
156  static inline int s_device = -1;
157  static inline spi_ioc_transfer s_transfer;
158  };
159 
160 }
bsp::asg::drv::SPI::init
static bool init()
Init function.
Definition: spi.hpp:54
bsp::asg::drv
Definition: display.hpp:60
u8
uint8_t u8
Unsigned integer definitions.
Definition: types.h:36
bsp::drv::SPIMode
SPIMode
Definition: spi.hpp:37
u64
uint64_t u64
Definition: types.h:39
u32
uint32_t u32
Definition: types.h:38
bsp::asg::drv::SPI::write
static void write(const std::array< u8, N > &data)
SPI write.
Definition: spi.hpp:115
bsp::asg::drv::SPI::deinit
static bool deinit()
Deinit function.
Definition: spi.hpp:86
bsp::asg::drv::SPI::read
static void read(std::array< u8, N > &data)
SPI receive.
Definition: spi.hpp:98
bsp::asg::drv::SPI::setMode
static void setMode(bsp::drv::SPIMode mode)
Set the spi mode (CPOL and CPHA)
Definition: spi.hpp:130
spi.hpp
Frontend for the SPI abstraction.
bsp::asg::drv::SPI
SPI implementation for Asgard.
Definition: spi.hpp:47
bsp::drv::SPIMode::_0
@ _0
CPOL = 0 | CPHA = 0.