Serial Wombat Arduino Library
Loading...
Searching...
No Matches
SerialWombatSPI.h
Go to the documentation of this file.
1#pragma once
2#include "SerialWombat.h"
5
6/*
7Copyright 2026 Broadwell Consulting Inc.
8
9"Serial Wombat" is a registered trademark of Broadwell Consulting Inc. in
10the United States. See SerialWombat.com for usage guidance.
11
12Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18
19The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29*/
30
31// Define values the same as in Arduino SPI.
32
33#ifndef SW_MSBFIRST
34#define SW_MSBFIRST 1
35#endif
36// Don't define LSB first because it's not supported.
37
38
39#ifndef SW_SPI_MODE0
40#define SW_SPI_MODE0 0x00
41#define SW_SPI_MODE1 0x04
42#define SW_SPI_MODE3 0x0C
43#endif
44
45
48public:
49 SerialWombatSPISettings(uint32_t clock = 0, uint8_t bitOrder = SW_MSBFIRST, uint8_t dataMode = SW_SPI_MODE0) {
50 (void)clock; // Clock is not configurable, so ignore this parameter.
51 (void)bitOrder; // Bit order is not configurable, so ignore this parameter.
52 (void)dataMode;
53 }
54};
55
96
98{
99public:
104 SerialWombatSPI(SerialWombatChip& serialWombat):SerialWombatPin(serialWombat){}
105
106
116 int16_t begin( uint8_t pin,uint8_t SPIModeparam, uint8_t MOSIpin = 255, uint8_t MISOpin = 255, uint8_t CSpin = 255)
117 {
118
119 _pin = pin;
121#ifdef SPI_MODE1
122 if (SPIModeparam == SPI_MODE1)
123 {
124 SPIModeparam = 1;
125 }
126#endif
127#ifdef SPI_MODE3
128 if (SPIModeparam == SPI_MODE3)
129 {
130 SPIModeparam = 3;
131 }
132#endif
133
134 if (SPIModeparam != 0 && SPIModeparam != 1 && SPIModeparam != 3)
135 {
137 }
138 uint8_t tx[8] = { 200, _pin,_pinMode, SPIModeparam,MOSIpin,MISOpin, CSpin, 0x55 };
139 uint8_t rx[8];
140 return _sw.sendPacket(tx, rx);
141
142 }
143
144 /* @brief Not needed for this class, included for congruency with Arduino SPIClass. Does nothing.
145
146 */
148 (void)settings; // Settings are not used because clock speed and bit order are fixed.
149 }
150
151 /* @brief Not needed for this class, included for congruency with Arduino SPIClass. Does nothing.
152
153 */
154 static void end(){}
155 /*
156 @brief Write to the SPI bus (MOSI pin) and also receive (MISO pin)
157 @param data The byte to send out the MOSI pin if configured. The byte received on the MISO pin during the transaction is returned.
158 @param csSaysStayLow If true, the chip select pin (if configured) will remain low after the transaction.
159 @return The byte received on the MISO pin during the transaction if configured.
160 */
161
162 uint8_t transfer(uint8_t data, bool csSaysStayLow = false)
163 {
164 uint8_t tx[8] = { 201, _pin, _pinMode, 8, data,0x55, 0x55, 0x55 };
165 uint8_t rx[8];
166
167 if (csSaysStayLow)
168 {
169 tx[0] = 202; // Use a different command to indicate that CS should stay low after the transaction.
170 }
171 int16_t result = _sw.sendPacket(tx, rx);
172 if (result < 0) {
173 // Handle error if needed. For now, just return 0 on error.
174 return 0;
175 }
176 return rx[4]; // The received byte is expected to be in rx[2].
177 }
178
179 /*
180 @brief Write to the SPI bus (MOSI pin) and also receive (MISO pin)
181 @param data The word to send out the MOSI pin if configured. The word will be send Least Significant Byte, most signficant bit first.
182 @param csSaysStayLow If true, the chip select pin (if configured) will remain low after the transaction.
183 @return The byte received on the MISO pin during the transaction if configured.
184 */
185
186 uint16_t transfer(uint16_t data, bool csSaysStayLow = false) {
187 uint8_t tx[8] = { 201, _pin, _pinMode, 16, SW_LE16(data), 0x55 };
188 uint8_t rx[8];
189
190 if (csSaysStayLow)
191 {
192 tx[0] = 202; // Use a different command to indicate that CS should stay low after the transaction.
193 }
194 int16_t result = _sw.sendPacket(tx, rx);
195 if (result < 0) {
196 // Handle error if needed. For now, just return 0 on error.
197 return 0;
198 }
199 return ((((uint16_t)rx[5]) << 8) + (uint16_t)rx[4]); // The received word is expected to be in rx[4] and rx[5].
200 }
201
202 /*
203 @brief Write to the SPI bus (MOSI pin) and also receive (MISO pin)
204 @param buf The array to send and receive data. The length of the array is determined by the count parameter.
205 @param csSaysStayLow If true, the chip select pin (if configured) will remain low after the transaction.
206 @return The byte received on the MISO pin during the transaction if configured.
207 */
208
209 void transfer(void* buf, size_t count, bool csSaysStayLow = false) {
210
211 if (_sw.isSW08())
212 {
213 while (count >= 5)
214 {
215 uint8_t tx[8] = { 204, _pin, _pinMode, ((uint8_t*)buf)[0], ((uint8_t*)buf)[1], ((uint8_t*)buf)[2], ((uint8_t*)buf)[3], ((uint8_t*)buf)[4] };
216 uint8_t rx[8];
217
218
219 count -= 5;
220 if (count == 0 && !csSaysStayLow)
221 {
222 --tx[0]; // Send a zero byte to indicate the end of the transaction and allow the chip select to go high again.
223 }
224 _sw.sendPacket(tx, rx);
225 ((uint8_t*)buf)[0] = rx[3];
226 ((uint8_t*)buf)[1] = rx[4];
227 ((uint8_t*)buf)[2] = rx[5];
228 ((uint8_t*)buf)[3] = rx[6];
229 ((uint8_t*)buf)[4] = rx[7];
230 buf = (void*)((uint8_t*)buf + 5);
231 }
232 if (count > 0)
233 {
234 uint8_t tx[8] = { 201, _pin, _pinMode,(uint8_t)(count * 8), 0x55, 0x55, 0x55, 0x55 };
235 for (size_t i = 0; i < count; ++i)
236 {
237 tx[4 + i] = ((uint8_t*)buf)[i];
238 }
239 uint8_t rx[8];
240
241 if (csSaysStayLow)
242 {
243 tx[0] = 202; // Use a different command to indicate that CS should stay low after the transaction.
244 }
245 int16_t result = _sw.sendPacket(tx, rx);
246 if (result < 0) {
247 // Handle error if needed. For now, just return 0 on error.
248 return;
249 }
250 for (size_t i = 0; i < count; ++i)
251 {
252 ((uint8_t*)buf)[i] = rx[4 + i];
253 }
254 }
255
256 }
257 else // SW18AB can only transfer 1 byte at a time to minimize the chance of frame overflows.
258 {
259 while (count > 0)
260 {
261 uint8_t tx[8] = { 202, _pin, _pinMode, 8, ((uint8_t*)buf)[0],0x55, 0x55, 0x55 };
262 uint8_t rx[8];
263
264 -- count;
265 if(count == 0 && !csSaysStayLow)
266 {
267 tx[0] = 201;
268 }
269 int16_t result = _sw.sendPacket(tx, rx);
270 if (result < 0) {
271 // Handle error if needed. For now, just return 0 on error.
272 return;
273 }
274 *(uint8_t*)buf = rx[4]; // The received byte is expected to be in rx[4].
275 buf = (void*)((uint8_t*)buf + 1);
276 }
277 }
278
279};
280
281 int16_t transferPacketUpTo32Bits(uint8_t* outBuf,uint8_t* inBuf, size_t bitCount, bool csSaysStayLow = false) {
282 if (bitCount > 32) {
283 // Handle error: bitCount exceeds maximum packet size.
284 return -1; // Return an error code or handle as appropriate.
285 }
286 uint8_t tx[8] = { 201, _pin, _pinMode, (uint8_t)(bitCount), 0x55, 0x55, 0x55, 0x55 };
287 if (csSaysStayLow) {
288 tx[0] = 202; // Use a different command to indicate that CS should stay low after the transaction.
289 }
290 uint8_t byteCount = (bitCount + 7) / 8; // Calculate the number of bytes needed to represent the bits.
291 if (outBuf != nullptr) {
292 for (size_t i = 0; i < byteCount; ++i) {
293 tx[4 + i] = outBuf[i];
294 }
295 }
296 uint8_t rx[8];
297
298 if (csSaysStayLow) {
299 tx[0] = 202; // Use a different command to indicate that CS should stay low after the transaction.
300 }
301 int16_t result = _sw.sendPacket(tx, rx);
302 if (result < 0) {
303 // Handle error if needed. For now, just return on error.
304 return result;
305 }
306 if (inBuf != nullptr) {
307 for (size_t i = 0; i < byteCount; ++i) {
308 inBuf[i] = rx[4 + i];
309 }
310 }
311 return bitCount;
312
313 };
314
315 int16_t transferPacket40Bits(uint8_t* outBuf,uint8_t* inBuf, bool csSaysStayLow = false) {
316
317 uint8_t tx[8] = { 203, _pin, _pinMode, 0x55, 0x55, 0x55, 0x55, 0x55 };
318 if (outBuf != nullptr) {
319 for (size_t i = 0; i < 5; ++i) {
320 tx[3 + i] = outBuf[i];
321 }
322 }
323 uint8_t rx[8];
324
325 if (csSaysStayLow) {
326 tx[0] = 204; // Use a different command to indicate that CS should stay low after the transaction.
327 }
328 int16_t result = _sw.sendPacket(tx, rx);
329 if (result < 0) {
330 // Handle error if needed. For now, just return on error.
331 return result;
332 }
333 if (inBuf != nullptr) {
334 for (size_t i = 0; i < 5; ++i) {
335 inBuf[i] = rx[3 + i];
336 }
337 }
338 return 40;
339};
340
341 int16_t setCSHigh() { // this will not be supported until 2.2.4
342
343 uint8_t tx[8] = { 205, _pin, _pinMode, 0x55, 0x55, 0x55, 0x55, 0x55 };
344 int16_t result = _sw.sendPacket(tx);
345 return result;
346};
347};
348
349
#define SW_LE16(_a)
Convert a uint16_t to two bytes in little endian format for array initialization.
@ PIN_MODE_SPI
(41)
@ SW_ERROR_INVALID_PARAMETER_3
(#17) The pin configuration parameter in Byte 3 was invalid
Class for a Serial Wombat chip. Each Serial Wombat chip on a project should have its own instance.
SerialWombatChip & _sw
SerialWombatPin(SerialWombatChip &serialWombatChip)
Instantiates a Serial Wombat Pin.
uint8_t pin()
Returns the current SW pin number. Used primarily for virtual calls by derived classes.
uint16_t transfer(uint16_t data, bool csSaysStayLow=false)
uint8_t transfer(uint8_t data, bool csSaysStayLow=false)
int16_t transferPacketUpTo32Bits(uint8_t *outBuf, uint8_t *inBuf, size_t bitCount, bool csSaysStayLow=false)
static void end()
SerialWombatSPI(SerialWombatChip &serialWombat)
Constructor for the SerialWombatSPI class.
int16_t begin(uint8_t pin, uint8_t SPIModeparam, uint8_t MOSIpin=255, uint8_t MISOpin=255, uint8_t CSpin=255)
int16_t transferPacket40Bits(uint8_t *outBuf, uint8_t *inBuf, bool csSaysStayLow=false)
static void beginTransaction(SerialWombatSPISettings settings)
void transfer(void *buf, size_t count, bool csSaysStayLow=false)
A class for storing SPI settings. This isn't actually used, but included for congruency with Arduino.
SerialWombatSPISettings(uint32_t clock=0, uint8_t bitOrder=SW_MSBFIRST, uint8_t dataMode=SW_SPI_MODE0)