Skyward boardcore
Loading...
Searching...
No Matches
SPITransaction.cpp
Go to the documentation of this file.
1/* Copyright (c) 2019-2021 Skyward Experimental Rocketry
2 * Authors: Luca Erbetta, Alberto Nidasio, Davide Mor
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#include "SPITransaction.h"
24
25#include <interfaces/endianness.h>
26
27namespace Boardcore
28{
29
30SPITransaction::SPITransaction(const SPISlave& slave) : slave(slave)
31{
32 slave.bus.configure(slave.config);
33}
34
36
37// Read, write and transfer operations in master mode
38
40{
41 slave.bus.select(slave.cs);
42 uint8_t data = slave.bus.read();
43 slave.bus.deselect(slave.cs);
44
45 return data;
46}
47
49{
50 slave.bus.select(slave.cs);
51 uint16_t data = slave.bus.read16();
52 slave.bus.deselect(slave.cs);
53
54 return data;
55}
56
58{
59 slave.bus.select(slave.cs);
60 uint32_t data = slave.bus.read24();
61 slave.bus.deselect(slave.cs);
62 return data;
63}
64
66{
67 slave.bus.select(slave.cs);
68 uint32_t data = slave.bus.read32();
69 slave.bus.deselect(slave.cs);
70 return data;
71}
72
73void SPITransaction::read(uint8_t* data, size_t size)
74{
75 slave.bus.select(slave.cs);
76 slave.bus.read(data, size);
77 slave.bus.deselect(slave.cs);
78}
79
80void SPITransaction::read16(uint16_t* data, size_t size)
81{
82 slave.bus.select(slave.cs);
83 slave.bus.read16(data, size);
84 slave.bus.deselect(slave.cs);
85}
86
87void SPITransaction::write(uint8_t data)
88{
89 slave.bus.select(slave.cs);
90 slave.bus.write(data);
91 slave.bus.deselect(slave.cs);
92}
93
94void SPITransaction::write16(uint16_t data)
95{
96 slave.bus.select(slave.cs);
97 slave.bus.write16(data);
98 slave.bus.deselect(slave.cs);
99}
100
101void SPITransaction::write24(uint32_t data)
102{
103 slave.bus.select(slave.cs);
104 slave.bus.write24(data);
105 slave.bus.deselect(slave.cs);
106}
107
108void SPITransaction::write32(uint32_t data)
109{
110 slave.bus.select(slave.cs);
111 slave.bus.write32(data);
112 slave.bus.deselect(slave.cs);
113}
114
115void SPITransaction::write(uint8_t* data, size_t size)
116{
117 slave.bus.select(slave.cs);
118 slave.bus.write(data, size);
119 slave.bus.deselect(slave.cs);
120}
121
122void SPITransaction::write16(uint16_t* data, size_t size)
123{
124 slave.bus.select(slave.cs);
125 slave.bus.write16(data, size);
126 slave.bus.deselect(slave.cs);
127}
128
129uint8_t SPITransaction::transfer(uint8_t data)
130{
131 slave.bus.select(slave.cs);
132 data = slave.bus.transfer(data);
133 slave.bus.deselect(slave.cs);
134
135 return data;
136}
137
138uint16_t SPITransaction::transfer16(uint16_t data)
139{
140 slave.bus.select(slave.cs);
141 data = slave.bus.transfer16(data);
142 slave.bus.deselect(slave.cs);
143
144 return data;
145}
146
147uint32_t SPITransaction::transfer24(uint32_t data)
148{
149 slave.bus.select(slave.cs);
150 data = slave.bus.transfer24(data);
151 slave.bus.deselect(slave.cs);
152
153 return data;
154}
155
156uint32_t SPITransaction::transfer32(uint32_t data)
157{
158 slave.bus.select(slave.cs);
159 data = slave.bus.transfer32(data);
160 slave.bus.deselect(slave.cs);
161
162 return data;
163}
164
165void SPITransaction::transfer(uint8_t* data, size_t size)
166{
167 slave.bus.select(slave.cs);
168 slave.bus.transfer(data, size);
169 slave.bus.deselect(slave.cs);
170}
171
172void SPITransaction::transfer16(uint16_t* data, size_t size)
173{
174 slave.bus.select(slave.cs);
175 slave.bus.transfer16(data, size);
176 slave.bus.deselect(slave.cs);
177}
178
179// Read, write and transfer operations with registers
180
182{
183 if (slave.config.writeBit == SPI::WriteBit::NORMAL)
184 reg |= 0x80;
185
186 slave.bus.select(slave.cs);
187 slave.bus.write(reg);
188 uint8_t data = slave.bus.read();
189 slave.bus.deselect(slave.cs);
190
191 return data;
192}
193
195{
196 if (slave.config.writeBit == SPI::WriteBit::NORMAL)
197 reg |= 0x80;
198
199 slave.bus.select(slave.cs);
200 slave.bus.write(reg);
201 uint16_t data = slave.bus.read16();
202 slave.bus.deselect(slave.cs);
203
204 if (slave.config.byteOrder == SPI::Order::LSB_FIRST)
205 data = swapBytes16(data);
206
207 return data;
208}
209
211{
212 if (slave.config.writeBit == SPI::WriteBit::NORMAL)
213 reg |= 0x80;
214
215 slave.bus.select(slave.cs);
216 slave.bus.write(reg);
217 uint32_t data = slave.bus.read24();
218 slave.bus.deselect(slave.cs);
219
220 if (slave.config.byteOrder == SPI::Order::LSB_FIRST)
221 data = swapBytes32(data) >> 8;
222
223 return data;
224}
225
227{
228 if (slave.config.writeBit == SPI::WriteBit::NORMAL)
229 reg |= 0x80;
230
231 slave.bus.select(slave.cs);
232 slave.bus.write(reg);
233 uint32_t data = slave.bus.read32();
234 slave.bus.deselect(slave.cs);
235
236 if (slave.config.byteOrder == SPI::Order::LSB_FIRST)
237 data = swapBytes32(data) >> 8;
238
239 return data;
240}
241
242void SPITransaction::readRegisters(uint8_t reg, uint8_t* data, size_t size)
243{
244 if (slave.config.writeBit == SPI::WriteBit::NORMAL)
245 reg |= 0x80;
246
247 slave.bus.select(slave.cs);
248 slave.bus.write(reg);
249 slave.bus.read(data, size);
250 slave.bus.deselect(slave.cs);
251}
252
253void SPITransaction::writeRegister(uint8_t reg, uint8_t data)
254{
255 if (slave.config.writeBit == SPI::WriteBit::INVERTED)
256 reg |= 0x80;
257
258 slave.bus.select(slave.cs);
259 slave.bus.write(reg);
260 slave.bus.write(data);
261 slave.bus.deselect(slave.cs);
262}
263
264void SPITransaction::writeRegister16(uint8_t reg, uint16_t data)
265{
266 if (slave.config.writeBit == SPI::WriteBit::INVERTED)
267 reg |= 0x80;
268
269 slave.bus.select(slave.cs);
270 slave.bus.write(reg);
271 slave.bus.write16(data);
272 slave.bus.deselect(slave.cs);
273}
274
275void SPITransaction::writeRegister24(uint8_t reg, uint32_t data)
276{
277 if (slave.config.writeBit == SPI::WriteBit::INVERTED)
278 reg |= 0x80;
279
280 slave.bus.select(slave.cs);
281 slave.bus.write(reg);
282 slave.bus.write24(data);
283 slave.bus.deselect(slave.cs);
284}
285
286void SPITransaction::writeRegister32(uint8_t reg, uint32_t data)
287{
288 if (slave.config.writeBit == SPI::WriteBit::INVERTED)
289 reg |= 0x80;
290
291 slave.bus.select(slave.cs);
292 slave.bus.write(reg);
293 slave.bus.write32(data);
294 slave.bus.deselect(slave.cs);
295}
296
297void SPITransaction::writeRegisters(uint8_t reg, uint8_t* data, size_t size)
298{
299 if (slave.config.writeBit == SPI::WriteBit::INVERTED)
300 reg |= 0x80;
301
302 slave.bus.select(slave.cs);
303 slave.bus.write(reg);
304 slave.bus.write(data, size);
305 slave.bus.deselect(slave.cs);
306}
307
308} // namespace Boardcore
Interface for low level access of a SPI bus as a master.
virtual void configure(SPIBusConfig config)=0
Configures the bus with the provided configuration parameters.
virtual uint32_t read32()
Reads 32 bits from the bus.
void write16(uint16_t data)
Writes a single half word to the bus.
void write(uint8_t data)
Writes a single byte to the bus.
uint8_t readRegister(uint8_t reg)
Reads an 8 bit register.
void writeRegister32(uint8_t reg, uint32_t data)
Writes a 32 bit register.
uint8_t read()
Reads a single byte from the bus.
void writeRegisters(uint8_t reg, uint8_t *data, size_t size)
Writes multiple bytes starting from the specified register.
virtual void write32(uint32_t data)
Writes 32 bits to the bus.
uint16_t transfer16(uint16_t data)
Full duplex transmission of one half word on the bus.
virtual uint32_t read24()
Reads 24 bits from the bus.
void writeRegister24(uint8_t reg, uint32_t data)
Writes a 24 bit register.
uint32_t readRegister32(uint8_t reg)
Reads a 32 bit register.
void readRegisters(uint8_t reg, uint8_t *data, size_t size)
Reads multiple bytes starting from the specified register.
void writeRegister(uint8_t reg, uint8_t data)
Writes an 8 bit register.
SPIBusInterface & getBus()
Returns the underlying bus for low level access.
virtual void write24(uint32_t data)
Writes 24 bits to the bus.
SPITransaction(const SPISlave &slave)
Instantiates a new SPITransaction, configuring the bus with the provided parameters.
virtual uint32_t transfer24(uint32_t data)
Full duplex transmission of 24 bits on the bus.
uint32_t readRegister24(uint8_t reg)
Reads a 24 bit register.
void writeRegister16(uint8_t reg, uint16_t data)
Writes a 16 bit register.
uint8_t transfer(uint8_t data)
Full duplex transmission of one byte on the bus.
uint16_t readRegister16(uint8_t reg)
Reads a 16 bit register.
virtual uint32_t transfer32(uint32_t data)
Full duplex transmission of 32 bits on the bus.
uint16_t read16()
Reads a single half word from the bus.
@ NORMAL
Normal write bit settings (0 for write, 1 for reads)
@ INVERTED
Inverted write bit settings (1 for write, 0 for reads)
This file includes all the types the logdecoder script will decode.
Contains information about a single SPI slave device.
SPIBusInterface & bus
Bus on which the slave is connected.