Serial Wombat Arduino Library
SerialWombatUART.h
Go to the documentation of this file.
1 #pragma once
2 #include "Stream.h"
3 #include "SerialWombat.h"
7 /*
8 Copyright 2020-2023 Broadwell Consulting Inc.
9 
10 "Serial Wombat" is a registered trademark of Broadwell Consulting Inc. in
11 the United States. See SerialWombat.com for usage guidance.
12 
13 Permission is hereby granted, free of charge, to any person obtaining a
14  * copy of this software and associated documentation files (the "Software"),
15  * to deal in the Software without restriction, including without limitation
16  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17  * and/or sell copies of the Software, and to permit persons to whom the
18  * Software is furnished to do so, subject to the following conditions:
19 
20 The above copyright notice and this permission notice shall be included in
21  * all copies or substantial portions of the Software.
22 
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
27  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
29  * OTHER DEALINGS IN THE SOFTWARE.
30 */
31 
95  public Stream, public SerialWombatPin
96 {
97 public:
102  SerialWombatUART(SerialWombatChip& serialWombat):SerialWombatPin(serialWombat){}
103 
104 
113  int16_t begin(uint32_t baudRate, uint8_t pin, uint8_t rxPin, uint8_t txPin,uint8_t HWinterface = 1 )
114  {
115  _rxPin = rxPin;
116  _txPin = txPin;
117  _pin = pin;
118  if (HWinterface == 2)
119  {
123 
124  }
125  else if (HWinterface == 1)
126  {
130  }
131  else
132  {
133  return (-1);
134  }
135  switch (baudRate)
136  {
137  case 300:
138  _baudMarker = 0;
139  break;
140  case 1200:
141  _baudMarker = 1;
142  break;
143 
144  case 2400:
145  _baudMarker = 2;
146  break;
147 
148  case 4800:
149  _baudMarker = 3;
150  break;
151  case 9600:
152  _baudMarker = 4;
153  break;
154  case 19200:
155  _baudMarker = 5;
156  break;
157 
158  case 38400:
159  _baudMarker = 6;
160  break;
161 
162  case 57600:
163  _baudMarker = 7;
164  break;
165 
166  default:
167  case 115200:
168  _baudMarker = 8;
169  break;
170  }
171  uint8_t tx[8] = { 200, _pin,_pinMode, _baudMarker,_rxPin,_txPin,0x55, 0x55 };
172  uint8_t rx[8];
173  return _sw.sendPacket(tx, rx);
174 
175  }
180  int available()
181 {
182  uint8_t tx[8] = { 201, _pin,_pinMode, 0,0x55,0x55,0x55,0x55 };
183  uint8_t rx[8];
184  _sw.sendPacket(tx, rx);
185  return (rx[4]);
186 }
191  int read()
192 {
193  uint8_t tx[8] = { 202, _pin,_pinMode, 1,0x55,0x55,0x55,0x55 };
194  uint8_t rx[8];
195  if (_sw.sendPacket(tx, rx) < 0)
196  {
197  return -1;
198  }
199 
200  if (rx[3] != 0)
201  {
202  return (rx[4]);
203  }
204  else
205  {
206  return (-1);
207  }
208 }
212  void flush()
213 {
214  uint8_t tx[8] = { 200, _pin,_pinMode, _baudMarker,_rxPin,_txPin,0x55 };
215  uint8_t rx[8];
216  _sw.sendPacket(tx, rx);
217 }
222  int peek()
223 {
224  uint8_t tx[8] = { 203, _pin,_pinMode,0x55,0x55,0x55,0x55,0x55 };
225  uint8_t rx[8];
226  _sw.sendPacket(tx, rx);
227  if (rx[4] > 0)
228  {
229  return (rx[5]);
230  }
231  else
232  {
233  return (-1);
234  }
235 }
247  size_t write(uint8_t data)
248 {
249  uint8_t tx[8] = { 201, _pin,_pinMode,1,data,0x55,0x55,0x55 };
250  _sw.sendPacket(tx);
251  return (1);
252 }
253 
266  size_t write(const uint8_t* buffer, size_t size)
267 {
268  size_t bytesAvailable = 0;
269  size_t bytesSent;
270  uint32_t timeoutMillis = millis() + timeout;
271 
272  for (bytesSent = 0; bytesSent < size ;)
273  {
274 
275  while (bytesAvailable < 4)
276  {
277  uint8_t peektx[8] = { 203, _pin,_pinMode,0x55,0x55,0x55,0x55,0x55 };
278  uint8_t peekrx[8];
279  _sw.sendPacket(peektx, peekrx);
280  bytesAvailable = peekrx[3];
281  if (timeoutMillis < millis())
282  {
283 // Serial.printf("UART TX TIMEOUT!\r\n");
284  return (bytesSent);
285  }
286  }
287  timeoutMillis = millis() + timeout;
288 
289  while (bytesSent < size && bytesAvailable > 0)
290  {
291  yield();
292  if ((size - bytesSent) < 7 || bytesAvailable < 7)
293  {
294  uint8_t tx[8] = { 201, _pin,_pinMode,0,0x55,0x55,0x55,0x55 };
295  uint8_t rx[8];
296  size_t txLen;
297  tx[3] = 0;
298  for (txLen = 0; txLen < 4 && txLen < bytesAvailable && bytesSent < size; ++txLen)
299  {
300  tx[4 + txLen] = buffer[bytesSent];
301  ++bytesSent;
302  ++tx[3];
303  }
304  _sw.sendPacket(tx, rx);
305  bytesAvailable = rx[3];
306  }
307  else
308  {
309  uint8_t tx[8] = { _tx7Command, 0x55,0x55,0x55,0x55,0x55,0x55,0x55 };
310  size_t txLen;
311 
312  for (txLen = 0; txLen < 7 ; ++txLen)
313  {
314  tx[1 + txLen] = buffer[bytesSent];
315  ++bytesSent;
316  --bytesAvailable;
317  }
318  _sw.sendPacket(tx);
319  }
320  }
321  }
322  return (bytesSent);
323 }
329 {
330  uint8_t peektx[8] = { 203, _pin,_pinMode,0x55,0x55,0x55,0x55,0x55 };
331  uint8_t peekrx[8];
332  _sw.sendPacket(peektx, peekrx);
333  return peekrx[3];
334 }
345  size_t readBytes(char* buffer, size_t length)
346 {
347  int index = 0;
348  int bytesAvailable = 0;
349  uint32_t timeoutMillis = millis() + timeout;
350  while (length > 0 && timeoutMillis > millis())
351  {
352  yield();
353  int bytecount = 4;
354  if (length < 4)
355  {
356  bytecount = length;
357  }
358  {
359 
360  uint8_t tx[8] = { 202, _pin,_pinMode, (uint8_t) bytecount,0x55,0x55,0x55,0x55 };
361  uint8_t rx[8];
362  _sw.sendPacket(tx, rx);
363  bytesAvailable = rx[3];
364 
365  if (bytesAvailable == 0)
366  {
367  continue;
368  }
369  else
370  {
371  timeoutMillis = millis() + timeout;
372  }
373  uint8_t bytesReturned = bytecount;
374  if (rx[3] < bytecount)
375  {
376  bytesReturned = rx[3];
377  }
378  for (int i = 0; i < bytesReturned; ++i)
379  {
380  buffer[index] = rx[i + 4];
381  ++index;
382  --bytesAvailable;
383  --length;
384 
385  }
386  }
387  while (bytesAvailable >= 7 && length >= 7)
388  {
389  uint8_t tx[8] = { _rx7Command, 0x55,0x55,0x55,0x55,0x55,0x55,0x55 };
390  uint8_t rx[8];
391  _sw.sendPacket(tx, rx);
392  for (int i = 0; i <7; ++i)
393  {
394  buffer[index] = rx[i + 1];
395  ++index;
396  --bytesAvailable;
397  --length;
398 
399  }
400  yield();
401  }
402 
403  }
404 
405  return (index);
406 }
407 
408 
409  void setTimeout(long timeout_mS)
410 {
411  if (timeout_mS == 0)
412  {
413  timeout = 0x80000000;
414  }
415  else
416  {
417  timeout = timeout_mS;
418  }
419 }
420 protected:
421  uint8_t _rxPin = 255;
422  uint8_t _txPin = 255;
423  uint8_t _baudMarker = 0;
424  uint32_t timeout = 5000;
428 };
429 
430 
431 
479 {
480 
481 public:
482 
483 
484  SerialWombatSWUART(SerialWombatChip& serialWombatChip):SerialWombatUART(serialWombatChip){}
494  int16_t begin(uint32_t baudRate, uint8_t pin, uint8_t rxPin, uint8_t txPin, uint16_t userMemoryOffset, uint16_t rxLength, uint16_t txLength)
495 {
496  _rxPin = rxPin;
497  _txPin = txPin;
498  _pin = pin;
499 
501 
502  switch (baudRate)
503  {
504  case 300:
505  _baudMarker = 0;
506  break;
507  case 1200:
508  _baudMarker = 1;
509  break;
510 
511  case 2400:
512  _baudMarker = 2;
513  break;
514 
515  case 4800:
516  _baudMarker = 3;
517  break;
518  case 9600:
519  _baudMarker = 4;
520  break;
521  case 19200:
522  _baudMarker = 5;
523  break;
524 
525  case 38400:
526  _baudMarker = 6;
527  break;
528 
529  case 57600:
530  _baudMarker = 7;
531  break;
532 
533  default:
534  case 115200:
535  _baudMarker = 7; // Limit to 57600
536  break;
537  }
538  uint8_t tx[8] = { 200, _pin,_pinMode, _baudMarker,_rxPin,_txPin,0x55, 0x55 };
539  uint8_t rx[8];
540 
541  int16_t result = _sw.sendPacket(tx, rx);
542  if (result < 0)
543  {
544  return (result);
545  }
546  int16_t rxoffset = 0;
547  //if (_rxPin != 255)
548  {
549  if (rxLength == 0)
550  {
551  rxLength = 2;
552  }
553  rxoffset = rxQueue.begin(userMemoryOffset, rxLength);
554  if (rxoffset >= 0)
555  {
556  userMemoryOffset += rxoffset;
557  }
558  else
559  {
560  return (0); // No memory should have been allocated.
561  }
562  }
563 
564  int16_t txoffset = 0;
565  //if (_txPin != 255)
566  {
567  if (txLength == 0)
568  {
569  txLength = 2;
570  }
571  txoffset = txQueue.begin(userMemoryOffset, txLength);
572  if (txoffset >= 0)
573  {
574  userMemoryOffset += txoffset;
575  }
576  else
577  {
578  return rxoffset;
579  }
580  }
581 
582  uint8_t tx5[] = { 205,_pin,_pinMode,SW_LE16(txQueue.startIndex) };
583  result = _sw.sendPacket(tx5);
584  if (result < 0) return (result);
585 
586 
587  uint8_t tx6[] = { 206,_pin,_pinMode,SW_LE16(rxQueue.startIndex) };
588  result = _sw.sendPacket(tx6);
589  if (result < 0) return (result);
590 
591  return (txoffset + rxoffset);
592 }
593 
597  int16_t begin(uint32_t baudRate, uint8_t pin, uint8_t rxPin, uint8_t txPin, uint8_t HWinterface) = delete;
598 
611  size_t write(const uint8_t* buffer, size_t size)
612 {
613  return (txQueue.write(buffer, size));
614 }
615 
624 private:
625  using SerialWombatUART::begin; //make parent class begin unavaialble
626 
627 };
628 
SerialWombatChip
Class for a Serial Wombat chip. Each Serial Wombat chip on a project should have its own instance.
Definition: SerialWombat.h:286
SerialWombatUART::_txPin
uint8_t _txPin
Definition: SerialWombatUART.h:422
SerialWombatQueue::write
size_t write(uint8_t data)
Write a byte to the Serial Wombat Queue /.
Definition: SerialWombatQueue.h:140
SerialWombatUART::write
size_t write(const uint8_t *buffer, size_t size)
Write bytes to the SerialWombatUART for Transmit.
Definition: SerialWombatUART.h:266
PIN_MODE_UART1_RX_TX
@ PIN_MODE_UART1_RX_TX
(23)
Definition: SerialWombat.h:262
SerialWombatQueue::startIndex
uint16_t startIndex
Definition: SerialWombatQueue.h:392
SerialWombatUART::_rxPin
uint8_t _rxPin
Definition: SerialWombatUART.h:421
SerialWombatCommands::COMMAND_UART0_RX_7BYTES
@ COMMAND_UART0_RX_7BYTES
(0xB1)
SerialWombatUART::SerialWombatUART
SerialWombatUART(SerialWombatChip &serialWombat)
Constructor for the SerialWombatUART class. Only one instance is allowed per SerialWombatChip 4B.
Definition: SerialWombatUART.h:102
SerialWombatSWUART::SerialWombatSWUART
SerialWombatSWUART(SerialWombatChip &serialWombatChip)
Definition: SerialWombatUART.h:484
SerialWombatPin::_sw
SerialWombatChip & _sw
Definition: SerialWombatPin.h:134
PIN_MODE_SW_UART
@ PIN_MODE_SW_UART
(13)
Definition: SerialWombat.h:254
SerialWombatSWUART::txQueue
SerialWombatQueue txQueue
SerialWombatQueue created on the Serial Wombat chip for data to be sent by the SerialWombatSWUART.
Definition: SerialWombatUART.h:623
SerialWombatUART::write
size_t write(uint8_t data)
Write a byte to the SerialWombatUART for Transmit.
Definition: SerialWombatUART.h:247
SerialWombatUART::flush
void flush()
Discard all received bytes.
Definition: SerialWombatUART.h:212
SerialWombatUART::begin
int16_t begin(uint32_t baudRate, uint8_t pin, uint8_t rxPin, uint8_t txPin, uint8_t HWinterface=1)
Definition: SerialWombatUART.h:113
SerialWombatCommands::COMMAND_UART1_TX_7BYTES
@ COMMAND_UART1_TX_7BYTES
(0xB2)
SerialWombatSWUART::rxQueue
SerialWombatQueue rxQueue
SerialWombatQueue created on the Serial Wombat chip for data received by the SerialWombatSWUART.
Definition: SerialWombatUART.h:619
SerialWombat.h
SerialWombatUART
A class for the Serial Wombat 4B or SW18AB chips which creates an I2C to UART Bridge.
Definition: SerialWombatUART.h:94
SerialWombatUART::availableForWrite
int availableForWrite()
Queries the SerialWombatUART for the amount of free TX queue space.
Definition: SerialWombatUART.h:328
SerialWombatUART::available
int available()
Queries the SerialWombatUART for number bytes available to read.
Definition: SerialWombatUART.h:180
SerialWombatPin
Describes a Serial Wombat Pin. Is base class for other pin modes.
Definition: SerialWombatPin.h:38
SerialWombatUART::readBytes
size_t readBytes(char *buffer, size_t length)
Reads a specified number of bytes from the SerialWombatUART RX queue.
Definition: SerialWombatUART.h:345
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
SerialWombatUART::read
int read()
Reads a byte from the SerialWombatUART.
Definition: SerialWombatUART.h:191
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
SerialWombatUART::setTimeout
void setTimeout(long timeout_mS)
Definition: SerialWombatUART.h:409
SerialWombatUART::_rx7Command
uint8_t _rx7Command
Definition: SerialWombatUART.h:427
SerialWombatUART::peek
int peek()
Query the SerialWombatUART for the next avaialble byte, but don't remove it from the queue.
Definition: SerialWombatUART.h:222
SerialWombatPin::pin
uint8_t pin()
Returns the current SW pin number. Used primarily for virtual calls by derived classes.
Definition: SerialWombatPin.h:121
SerialWombatUART::_tx7Command
uint8_t _tx7Command
Definition: SerialWombatUART.h:426
SerialWombatCommands::COMMAND_UART1_RX_7BYTES
@ COMMAND_UART1_RX_7BYTES
(0xB3)
SerialWombatPin::_pin
uint8_t _pin
Definition: SerialWombatPin.h:133
SerialWombatUART::timeout
uint32_t timeout
Definition: SerialWombatUART.h:424
SerialWombatUART::_baudMarker
uint8_t _baudMarker
Definition: SerialWombatUART.h:423
SW_LE16
#define SW_LE16(_a)
Convert a uint16_t to two bytes in little endian format for array initialization.
Definition: SerialWombat.h:41
SerialWombatSWUART::begin
int16_t begin(uint32_t baudRate, uint8_t pin, uint8_t rxPin, uint8_t txPin, uint16_t userMemoryOffset, uint16_t rxLength, uint16_t txLength)
Definition: SerialWombatUART.h:494
SerialWombatQueue
A Class representing a Queue in the User Ram area on the Serial Wombat Chip.
Definition: SerialWombatQueue.h:41
SerialWombatUART::_pinMode
uint8_t _pinMode
Definition: SerialWombatUART.h:425
SerialWombatSWUART::write
size_t write(const uint8_t *buffer, size_t size)
Write bytes to the SerialWombatUART for Transmit.
Definition: SerialWombatUART.h:611
PIN_MODE_UART_RX_TX
@ PIN_MODE_UART_RX_TX
(17)
Definition: SerialWombat.h:258
SerialWombatCommands::COMMAND_UART0_TX_7BYTES
@ COMMAND_UART0_TX_7BYTES
(0xB0)
SerialWombatSWUART
A class for the Serial Wombat 4B or SW18AB chips which creates a software based UART on the SW18AB.
Definition: SerialWombatUART.h:478