Serial Wombat Arduino Library

Loading...
Searching...
No Matches
SerialWombatUART.h
Go to the documentation of this file.
1#pragma once
2#include "Stream.h"
3#include "SerialWombat.h"
6
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
93
94 class SerialWombatUART :
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 {
120 _pinMode = PIN_MODE_UART1_RX_TX;
121 _tx7Command = (uint8_t)SerialWombatCommands::COMMAND_UART1_TX_7BYTES;
122 _rx7Command = (uint8_t)SerialWombatCommands::COMMAND_UART1_RX_7BYTES;
123
124 }
125 else if (HWinterface == 1)
126 {
127 _pinMode = PIN_MODE_UART_RX_TX;
128 _tx7Command = (uint8_t)SerialWombatCommands::COMMAND_UART0_TX_7BYTES;
129 _rx7Command = (uint8_t)SerialWombatCommands::COMMAND_UART0_RX_7BYTES;
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 }
176
180 virtual 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}
187
191 virtual 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}
209
212 virtual 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}
218
222 virtual 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}
236
247 virtual 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 virtual 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 delay(0);//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}
324
328 virtual int availableForWrite()
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}
335
345 virtual 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 virtual 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;
425 uint8_t _pinMode = PIN_MODE_UART_RX_TX;
426 uint8_t _tx7Command = (uint8_t)SerialWombatCommands::COMMAND_UART0_TX_7BYTES;
427 uint8_t _rx7Command = (uint8_t)SerialWombatCommands::COMMAND_UART0_RX_7BYTES;
428};
429
430
431
478 class SerialWombatSWUART : public SerialWombatUART
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
500 _pinMode = PIN_MODE_SW_UART;
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 = 1)
598{
599 _rxPin = rxPin;
600 _txPin = txPin;
601 _pin = pin;
602 rxQueue.startIndex = 0xFFFF;
603 txQueue.startIndex = 0xFFFF;
604
605 (void)HWinterface; // unused
606 _pinMode = PIN_MODE_SW_UART;
607
608 switch (baudRate)
609 {
610 case 300:
611 _baudMarker = 0;
612 break;
613 case 1200:
614 _baudMarker = 1;
615 break;
616
617 case 2400:
618 _baudMarker = 2;
619 break;
620
621 case 4800:
622 _baudMarker = 3;
623 break;
624 case 9600:
625 _baudMarker = 4;
626 break;
627 case 19200:
628 _baudMarker = 5;
629 break;
630
631 case 38400:
632 _baudMarker = 6;
633 break;
634
635 case 57600:
636 _baudMarker = 7;
637 break;
638
639 default:
640 case 115200:
641 _baudMarker = 7; // Limit to 57600
642 break;
643 }
644 uint8_t tx[8] = { 200, _pin,_pinMode, _baudMarker,_rxPin,_txPin,0x55, 0x55 };
645 uint8_t rx[8];
646
647 int16_t result = _sw.sendPacket(tx, rx);
648 return (result);
649}
650
662 size_t write(const uint8_t* buffer, size_t size)
663{
664 if (txQueue.startIndex != 0xFFFF)
665{
666 return (txQueue.write(buffer, size));
667}
668 else
669 {
670 size_t sent = 0;
671 while (sent < size)
672 {
673 uint8_t bytesToSend = 4;
674 if ((size - sent) < bytesToSend)
675 {
676 bytesToSend = size - sent;
677 }
678 uint8_t tx[8] = { 201, _pin,_pinMode, bytesToSend, 0x55,0x55,0x55,0x55};
679 uint8_t rx[8];
680 for (int i = 0; i < bytesToSend; ++i)
681 {
682 tx[4 + i] = buffer[sent + i];
683 }
684 _sw.sendPacket(tx, rx);
685 sent += bytesToSend;
686 if (rx[3] < 4) // almost full
687 {
688 return (sent);
689 }
690 delay(0);
691 }
692 return (sent);
693 }
694}
695
696/*
697 @brief Reads a specified number of bytes from the SerialWombatUART RX queue
698 @param buffer An array into which to put received bytes
699 @param length The maximum number of bytes to be received
700 @return the number of bytes written to buffer
701
702 This function will read bytes from the SerialWombatUART RX queue into buffer.
703 If 'length' characters are not available to read then the value returned
704 will be less than length.
705 */
706 size_t readBytes(char* buffer, size_t length)
707{
708 if (rxQueue.startIndex != 0xFFFF)
709 {
710 return (rxQueue.readBytes(buffer, length));
711 }
712 else
713 {
714 size_t bytesAvailable = 1;
715 size_t bytesReceived = 0;
716 while (bytesAvailable && (bytesReceived < length))
717 {
718 uint8_t bytesRequested = 4;
719 if (length - bytesReceived < 4)
720 {
721 bytesRequested = length - bytesReceived;
722 }
723 uint8_t tx[8] = { 202, _pin,_pinMode, bytesRequested, 0x55,0x55,0x55,0x55};
724 uint8_t rx[8];
725 _sw.sendPacket(tx, rx);
726 if (rx[3] > 4)
727 {
728 rx[3] = 4;
729 }
730 for (int i = 0; i < rx[3]; ++i)
731 {
732 buffer[bytesReceived] = rx[4 + i];
733 ++ bytesReceived;
734 }
735 bytesAvailable = rx[3];
736 delay(0);
737 }
738 return (bytesReceived);
739
740 }
741
742}
743
747 SerialWombatQueue rxQueue{ _sw };
751 SerialWombatQueue txQueue{ _sw };
752
753 uint8_t bytesToTransmit()
754 {
755 uint8_t tx[8] = { 203, _pin,_pinMode, 0x55, 0x55,0x55,0x55,0x55};
756 uint8_t rx[8];
757 if( _sw.sendPacket(tx, rx) >= 0)
758{
759 return(rx[6]);
760}
761 return 0;
762 }
763 private:
764 using SerialWombatUART::begin; //make parent class begin unavaialble
765
766};
767
SerialWombat.h
SW_LE16
#define SW_LE16(_a)
Convert a uint16_t to two bytes in little endian format for array initialization.
Definition SerialWombat.h:46
SerialWombatCommands::COMMAND_UART1_RX_7BYTES
@ COMMAND_UART1_RX_7BYTES
(0xB3)
Definition SerialWombat.h:230
SerialWombatCommands::COMMAND_UART0_TX_7BYTES
@ COMMAND_UART0_TX_7BYTES
(0xB0)
Definition SerialWombat.h:227
SerialWombatCommands::COMMAND_UART1_TX_7BYTES
@ COMMAND_UART1_TX_7BYTES
(0xB2)
Definition SerialWombat.h:229
SerialWombatCommands::COMMAND_UART0_RX_7BYTES
@ COMMAND_UART0_RX_7BYTES
(0xB1)
Definition SerialWombat.h:228
PIN_MODE_UART_RX_TX
@ PIN_MODE_UART_RX_TX
(17)
Definition SerialWombat.h:277
PIN_MODE_UART1_RX_TX
@ PIN_MODE_UART1_RX_TX
(23)
Definition SerialWombat.h:281
PIN_MODE_SW_UART
@ PIN_MODE_SW_UART
(13)
Definition SerialWombat.h:273
SerialWombatChip
Class for a Serial Wombat chip. Each Serial Wombat chip on a project should have its own instance.
Definition SerialWombat.h:313
SerialWombatPin::_sw
SerialWombatChip & _sw
Definition SerialWombatPin.h:214
SerialWombatPin::SerialWombatPin
SerialWombatPin(SerialWombatChip &serialWombatChip)
Instantiates a Serial Wombat Pin.
Definition SerialWombatPin.h:45
SerialWombatPin::_pin
uint8_t _pin
Definition SerialWombatPin.h:213
SerialWombatPin::pin
uint8_t pin()
Returns the current SW pin number. Used primarily for virtual calls by derived classes.
Definition SerialWombatPin.h:120
SerialWombatQueue
A Class representing a Queue in the User Ram area on the Serial Wombat Chip.
Definition SerialWombatQueue.h:42
SerialWombatSWUART::txQueue
SerialWombatQueue txQueue
SerialWombatQueue created on the Serial Wombat chip for data to be sent by the SerialWombatSWUART.
Definition SerialWombatUART.h:751
SerialWombatSWUART::bytesToTransmit
uint8_t bytesToTransmit()
Definition SerialWombatUART.h:753
SerialWombatSWUART::readBytes
size_t readBytes(char *buffer, size_t length)
Reads a specified number of bytes from the SerialWombatUART RX queue.
Definition SerialWombatUART.h:706
SerialWombatSWUART::rxQueue
SerialWombatQueue rxQueue
SerialWombatQueue created on the Serial Wombat chip for data received by the SerialWombatSWUART.
Definition SerialWombatUART.h:747
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
SerialWombatSWUART::write
size_t write(const uint8_t *buffer, size_t size)
Write bytes to the SerialWombatUART for Transmit.
Definition SerialWombatUART.h:662
SerialWombatSWUART::begin
int16_t begin(uint32_t baudRate, uint8_t pin, uint8_t rxPin, uint8_t txPin, uint8_t HWinterface=1)
This method uses 32 byte buffers in pin memory rather than user ram.
Definition SerialWombatUART.h:597
SerialWombatSWUART::SerialWombatSWUART
SerialWombatSWUART(SerialWombatChip &serialWombatChip)
Definition SerialWombatUART.h:484
SerialWombatUART::write
virtual size_t write(const uint8_t *buffer, size_t size)
Write bytes to the SerialWombatUART for Transmit.
Definition SerialWombatUART.h:266
SerialWombatUART::timeout
uint32_t timeout
Definition SerialWombatUART.h:424
SerialWombatUART::_rxPin
uint8_t _rxPin
Definition SerialWombatUART.h:421
SerialWombatUART::SerialWombatUART
SerialWombatUART(SerialWombatChip &serialWombat)
Constructor for the SerialWombatUART class. Only one instance is allowed per SerialWombatChip 4B.
Definition SerialWombatUART.h:102
SerialWombatUART::setTimeout
virtual void setTimeout(long timeout_mS)
Definition SerialWombatUART.h:409
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
SerialWombatUART::_tx7Command
uint8_t _tx7Command
Definition SerialWombatUART.h:426
SerialWombatUART::_baudMarker
uint8_t _baudMarker
Definition SerialWombatUART.h:423
SerialWombatUART::readBytes
virtual size_t readBytes(char *buffer, size_t length)
Reads a specified number of bytes from the SerialWombatUART RX queue.
Definition SerialWombatUART.h:345
SerialWombatUART::_pinMode
uint8_t _pinMode
Definition SerialWombatUART.h:425
SerialWombatUART::available
virtual int available()
Queries the SerialWombatUART for number bytes available to read.
Definition SerialWombatUART.h:180
SerialWombatUART::_txPin
uint8_t _txPin
Definition SerialWombatUART.h:422
SerialWombatUART::_rx7Command
uint8_t _rx7Command
Definition SerialWombatUART.h:427
SerialWombatUART::availableForWrite
virtual int availableForWrite()
Queries the SerialWombatUART for the amount of free TX queue space.
Definition SerialWombatUART.h:328
SerialWombatUART::write
virtual size_t write(uint8_t data)
Write a byte to the SerialWombatUART for Transmit.
Definition SerialWombatUART.h:247
SerialWombatUART::flush
virtual void flush()
Discard all received bytes.
Definition SerialWombatUART.h:212
SerialWombatUART::peek
virtual int peek()
Query the SerialWombatUART for the next avaialble byte, but don't remove it from the queue.
Definition SerialWombatUART.h:222
SerialWombatUART::read
virtual int read()
Reads a byte from the SerialWombatUART.
Definition SerialWombatUART.h:191