Serial Wombat Arduino Library
SerialWombatQueue.h
Go to the documentation of this file.
1 #pragma once
2 /*
3 Copyright 2020-2023 Broadwell Consulting Inc.
4 
5 "Serial Wombat" is a registered trademark of Broadwell Consulting Inc. in
6 the United States. See SerialWombat.com for usage guidance.
7 
8 Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24  * OTHER DEALINGS IN THE SOFTWARE.
25 */
26 
27 #include <stdint.h>
28 #include "SerialWombat.h"
29 
30 
34 };
35 
41 class SerialWombatQueue : public Stream
42 {
43 public:
47 
48  SerialWombatQueue(SerialWombatChip& serialWombat):_sw(serialWombat)
49  {
50  _sw = serialWombat;
51  }
52 
60 
62 {
63  startIndex = index;
64  length = length;
65  uint8_t tx[] = {(uint8_t) SerialWombatCommands::COMMAND_BINARY_QUEUE_INITIALIZE ,SW_LE16(index),SW_LE16(length),(uint8_t)qtype, 0x55,0x55 };
66  uint8_t rx[8];
67  int16_t result = _sw.sendPacket(tx,rx);
68  if (result < 0)
69  {
70  return result;
71  }
72  else
73  {
74  return ((int16_t)(rx[3] + 256 * rx[4]));
75  }
76 }
77 
81 
82  int available()
83 {
84  uint8_t tx[] = {(uint8_t)SerialWombatCommands::COMMAND_BINARY_QUEUE_INFORMATION ,SW_LE16(startIndex),0x55,0x55,0x55,0x55,0x55 };
85  uint8_t rx[8];
86  int16_t sendResult = _sw.sendPacket(tx,rx);
87  if (sendResult >= 0)
88  {
89  return (rx[4] + 256 * rx[5]);
90  }
91  return (0);
92 }
96 
97  int read()
98 {
99  uint8_t tx[] = { (uint8_t)SerialWombatCommands::COMMAND_BINARY_QUEUE_READ_BYTES ,SW_LE16(startIndex),1,0x55,0x55,0x55,0x55 };
100  uint8_t rx[8];
101  int16_t sendResult = _sw.sendPacket(tx, rx);
102  if (sendResult >= 0)
103  {
104  if (rx[1] == 1)
105  return (rx[2]);
106  }
107  return (-1);
108 }
111 
112  void flush()
113 {
115 }
119 
120  int peek()
121 {
122  uint8_t tx[] = { (uint8_t)SerialWombatCommands::COMMAND_BINARY_QUEUE_INFORMATION ,SW_LE16(startIndex),0x55,0x55,0x55,0x55,0x55 };
123  uint8_t rx[8];
124  int16_t sendResult = _sw.sendPacket(tx, rx);
125  if (sendResult >= 0)
126  {
127  if ((rx[4] + 256 * rx[5]) > 0)
128  {
129  return(rx[3]);
130  }
131  }
132  return (-1);
133 }
138 
140  size_t write(uint8_t data)
141 {
142  uint8_t tx[] = { (uint8_t)SerialWombatCommands::COMMAND_BINARY_QUEUE_ADD_BYTES ,SW_LE16(startIndex),1,data,0x55,0x55,0x55 };
143  uint8_t rx[8];
144  int16_t sendResult = _sw.sendPacket(tx, rx);
145  if (sendResult >= 0)
146  {
147 
148  return(rx[3]);
149  }
150  return (0);
151 }
152 
157 
159  size_t write(uint16_t data)
160  {
161  if (availableForWrite() < 2) return 0;
162  uint8_t tx[] = { (uint8_t)SerialWombatCommands::COMMAND_BINARY_QUEUE_ADD_BYTES ,SW_LE16(startIndex),2,SW_LE16(data),0x55,0x55};
163  uint8_t rx[8];
164  int16_t sendResult = _sw.sendPacket(tx, rx);
165  if (sendResult >= 0)
166  {
167 
168  return(rx[3]);
169  }
170  return (0);
171  }
183 
185  size_t write(uint16_t buffer[], size_t size)
186  {
187  return (write((const uint8_t*)buffer, size * 2));
188  }
200 
202  size_t write(const uint16_t* buffer, size_t size)
203  {
204  return (write((const uint8_t*)buffer,size*2));
205  }
206 
218 
219  size_t write(const uint8_t* buffer, size_t size)
220 {
221  uint8_t nextWriteSize;
222  uint16_t bytesWritten = 0;
223  uint32_t startTime = millis();
224 
225  //Write up to the first 4 bytes
226  if (size >= 4)
227  {
228  nextWriteSize = 4;
229  }
230  else
231  {
232  nextWriteSize = (uint8_t)size;
233  }
234  {
235  uint8_t tx[] = { (uint8_t)SerialWombatCommands::COMMAND_BINARY_QUEUE_ADD_BYTES ,SW_LE16(startIndex),0,0x55,0x55,0x55,0x55 };
236  uint8_t i;
237  for (i = 0; i < nextWriteSize; ++i)
238  {
239  tx[4 + i] = buffer[i];
240  }
241  tx[3] = nextWriteSize;
242  uint8_t rx[8];
243  int16_t sendResult = _sw.sendPacket(tx, rx);
244  if (sendResult < 0)
245  {
246  return(bytesWritten);
247  }
248  bytesWritten += rx[3];
249  }
250  while ((size - bytesWritten) >= 7)
251  {
252  yield();
254  buffer[bytesWritten],
255  buffer[bytesWritten + 1],
256  buffer[bytesWritten + 2],
257  buffer[bytesWritten + 3],
258  buffer[bytesWritten + 4],
259  buffer[bytesWritten + 5],
260  buffer[bytesWritten + 6] };
261 
262  uint8_t rx[8];
263  int16_t sendResult = _sw.sendPacket(tx, rx);
264  if (sendResult < 0)
265  {
266  return(bytesWritten);
267  }
268  bytesWritten += rx[3];
269  delay(0);
270  if (millis() > startTime + _timeout)
271  {
272  return(bytesWritten);
273  }
274  }
275 
276  while (size - bytesWritten > 0)
277  {
278  yield();
279  if (size - bytesWritten >= 4)
280  {
281  nextWriteSize = 4;
282  }
283  else
284  {
285  nextWriteSize = (uint8_t)(size - bytesWritten);
286  }
287  {
288  uint8_t tx[] = { (uint8_t)SerialWombatCommands::COMMAND_BINARY_QUEUE_ADD_BYTES ,SW_LE16(startIndex),0,0x55,0x55,0x55,0x55 };
289  uint8_t i;
290  for (i = 0; i < nextWriteSize; ++i)
291  {
292  tx[4 + i] = buffer[i + bytesWritten];
293  }
294  tx[3] = nextWriteSize;
295  uint8_t rx[8];
296  int16_t sendResult = _sw.sendPacket(tx, rx);
297  if (sendResult < 0)
298  {
299  return(bytesWritten);
300  }
301  bytesWritten += rx[3];
302  }
303  if (millis() > startTime + _timeout)
304  {
305  return(bytesWritten);
306  }
307  }
308  return (bytesWritten);
309 }
310 
314 
316 {
317  uint8_t tx[] = { (uint8_t)SerialWombatCommands::COMMAND_BINARY_QUEUE_INFORMATION ,SW_LE16(startIndex),0x55,0x55,0x55,0x55,0x55 };
318  uint8_t rx[8];
319  int16_t sendResult = _sw.sendPacket(tx, rx);
320  if (sendResult >= 0)
321  {
322  return (rx[6] + 256 * rx[7]);
323  }
324  return (0);
325 }
326 
336 
337  size_t readBytes(char* buffer, size_t length)
338 {
339  uint16_t bytesAvailable = 0;
340  uint32_t startTime = millis();
341 
342  {
343  uint8_t tx[] = { (uint8_t)SerialWombatCommands::COMMAND_BINARY_QUEUE_INFORMATION ,SW_LE16(startIndex),0x55,0x55,0x55,0x55,0x55 };
344  uint8_t rx[8];
345  int16_t sendResult = _sw.sendPacket(tx, rx);
346  if (sendResult >= 0)
347  {
348  bytesAvailable = (rx[4] + 256 * rx[5]);
349  }
350 
351  if (bytesAvailable < length)
352  {
353  length = bytesAvailable;
354  }
355  }
356  uint16_t bytesRead = 0;
357  while (bytesRead < length)
358  {
359  yield();
360  uint8_t bytesToRead =(uint8_t)( length - bytesRead);
361  if (bytesToRead > 6)
362  {
363  bytesToRead = 6;
364  }
365  uint8_t tx[] = { (uint8_t)SerialWombatCommands::COMMAND_BINARY_QUEUE_READ_BYTES ,SW_LE16(startIndex),bytesToRead,0x55,0x55,0x55,0x55 };
366  uint8_t rx[8];
367  int16_t sendResult = _sw.sendPacket(tx, rx);
368  if (sendResult >= 0)
369  {
370  uint8_t i;
371  for (i = 0; i < rx[1] && bytesRead < length; ++i)
372  {
373  buffer[bytesRead] = rx[2 + i];
374  ++bytesRead;
375  }
376 
377  }
378  else
379  {
380  return (bytesRead);
381  }
382  if (millis() > startTime + _timeout)
383  {
384  return(bytesRead);
385  }
386 
387  }
388  return bytesRead;
389 }
390 
391 
392  uint16_t startIndex = 0xFFFF;
393  uint16_t length = 0;
394 
395  void setTimeout(long timeout_mS)
396 {
397  _timeout = timeout_mS;
398 }
399 
409 
410  size_t readUInt16(uint16_t* buffer, size_t length)
411  {
412  uint16_t bytesAvailable = 0;
413 
414  uint8_t tx[] = { (uint8_t)SerialWombatCommands::COMMAND_BINARY_QUEUE_INFORMATION ,SW_LE16(startIndex),0x55,0x55,0x55,0x55,0x55 };
415  uint8_t rx[8];
416  int16_t sendResult = _sw.sendPacket(tx, rx);
417  if (sendResult >= 0)
418  {
419  bytesAvailable = (rx[4] + 256 * rx[5]);
420  }
421  uint16_t wordsAvailable = bytesAvailable /2;
422  if (wordsAvailable < length)
423  {
424  length = wordsAvailable ;
425  }
426  return readBytes((char*)buffer, length * 2) / 2;
427  }
428 
429  //TODO add copy interface
430 private:
431  SerialWombatChip& _sw;
432 
433 
434  uint32_t _timeout = 500;
435 };
SerialWombatChip
Class for a Serial Wombat chip. Each Serial Wombat chip on a project should have its own instance.
Definition: SerialWombat.h:286
SerialWombatQueue::write
size_t write(uint8_t data)
Write a byte to the Serial Wombat Queue /.
Definition: SerialWombatQueue.h:140
SerialWombatQueue::setTimeout
void setTimeout(long timeout_mS)
Definition: SerialWombatQueue.h:395
SerialWombatQueueType::QUEUE_TYPE_RAM_BYTE
@ QUEUE_TYPE_RAM_BYTE
A queue that queues byte-sized data in a queue in the User RAM area.
SerialWombatQueue::write
size_t write(uint16_t data)
Write an unsigned word to the Serial Wombat Queue /.
Definition: SerialWombatQueue.h:159
SerialWombatCommands::COMMAND_BINARY_QUEUE_INFORMATION
@ COMMAND_BINARY_QUEUE_INFORMATION
(0x94)
SerialWombatQueue::startIndex
uint16_t startIndex
Definition: SerialWombatQueue.h:392
SerialWombatQueue::length
uint16_t length
Definition: SerialWombatQueue.h:393
SerialWombatQueue::flush
void flush()
Discard all received bytes.
Definition: SerialWombatQueue.h:112
SerialWombatCommands::COMMAND_BINARY_QUEUE_READ_BYTES
@ COMMAND_BINARY_QUEUE_READ_BYTES
(0x93)
SerialWombat.h
SerialWombatQueue::read
int read()
Reads a byte from the Serial Wombat /.
Definition: SerialWombatQueue.h:97
SerialWombatQueue::SerialWombatQueue
SerialWombatQueue(SerialWombatChip &serialWombat)
Constructor for SerialWombatWS2812 class /.
Definition: SerialWombatQueue.h:48
SerialWombatQueue::write
size_t write(const uint8_t *buffer, size_t size)
Write bytes to the Serial Wombat Queue /.
Definition: SerialWombatQueue.h:219
SerialWombatQueue::begin
int16_t begin(uint16_t index, uint16_t length, SerialWombatQueueType qtype=SerialWombatQueueType::QUEUE_TYPE_RAM_BYTE)
Initialize a Serial Wombat Queue (RAM Bytes) in User Memory Area on Serial Wombat Chip / /.
Definition: SerialWombatQueue.h:61
SerialWombatQueueType::QUEUE_TYPE_RAM_BYTE_SHIFT
@ QUEUE_TYPE_RAM_BYTE_SHIFT
A queue that queues byte-sized data in a queue in the User RAM area.
SerialWombatChip::sendPacket
int sendPacket(uint8_t tx[], uint8_t rx[])
Send an 8 byte packet to the Serial Wombat chip and wait for 8 bytes back.
Definition: SerialWombat.cpp:115
SerialWombatQueueType
SerialWombatQueueType
Definition: SerialWombatQueue.h:31
SerialWombatQueue::readUInt16
size_t readUInt16(uint16_t *buffer, size_t length)
Reads a specified number of unsigned 16 bit words from the Serial Wombat Queue /.
Definition: SerialWombatQueue.h:410
SerialWombatQueue::readBytes
size_t readBytes(char *buffer, size_t length)
Reads a specified number of bytes from the Serial Wombat Queue /.
Definition: SerialWombatQueue.h:337
SerialWombatQueue::available
int available()
Queries the Serial Wombat for number bytes available to read /.
Definition: SerialWombatQueue.h:82
SW_LE16
#define SW_LE16(_a)
Convert a uint16_t to two bytes in little endian format for array initialization.
Definition: SerialWombat.h:41
SerialWombatQueue::peek
int peek()
Query the Serial Wombat for the next avaialble byte, but don't remove it from the queue /.
Definition: SerialWombatQueue.h:120
SerialWombatQueue
A Class representing a Queue in the User Ram area on the Serial Wombat Chip.
Definition: SerialWombatQueue.h:41
SerialWombatQueue::write
size_t write(const uint16_t *buffer, size_t size)
Write unsigned words to the Serial Wombat Queue /.
Definition: SerialWombatQueue.h:202
SerialWombatCommands::COMMAND_BINARY_QUEUE_ADD_7BYTES
@ COMMAND_BINARY_QUEUE_ADD_7BYTES
(0x92)
SerialWombatQueue::availableForWrite
int availableForWrite()
Queries the Serial Wombat for the amount of free queue space /.
Definition: SerialWombatQueue.h:315
SerialWombatCommands::COMMAND_BINARY_QUEUE_INITIALIZE
@ COMMAND_BINARY_QUEUE_INITIALIZE
(0x90)
SerialWombatQueue::write
size_t write(uint16_t buffer[], size_t size)
Write unsigned words to the Serial Wombat Queue /.
Definition: SerialWombatQueue.h:185
SerialWombatCommands::COMMAND_BINARY_QUEUE_ADD_BYTES
@ COMMAND_BINARY_QUEUE_ADD_BYTES
(0x91)