Serial Wombat Arduino Library
Loading...
Searching...
No Matches
SerialWombat.h
Go to the documentation of this file.
1#ifndef SERIAL_WOMBAT_H__
2#define SERIAL_WOMBAT_H__
3
4/*
5Copyright 2020-2026 Broadwell Consulting Inc.
6
7"Serial Wombat" is a registered trademark of Broadwell Consulting Inc. in
8the United States. See SerialWombat.com for usage guidance.
9
10Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16
17The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26 * OTHER DEALINGS IN THE SOFTWARE.
27*/
28
29#include <stdint.h>
30#include "Stream.h"
31//#include "Serial.h" // Using "" rather than <> for compatibility with Visual C++ simulation project
32#include "Wire.h"// Using "" rather than <> for compatibility with Visual C++ simulation project
33#include "Arduino.h"
34#ifndef INPUT
35#define INPUT 0x0
36#endif
37
38
41
42
43#include "SerialWombatErrors.h"
44
46#define SW_LE16(_a) (uint8_t)((_a) & 0xFF), (uint8_t)((_a) >>8)
47
49#define SW_LE32(_a) (uint8_t)((_a) & 0xFF), (uint8_t)((_a) >>8) , (uint8_t)((_a) >>16), (uint8_t)((_a) >>24)
50
51#define ARRAY_UINT32(_array,_index) ((((uint32_t) _array[_index +3])<<24) + (((uint32_t) _array[_index +2])<<16) + (((uint32_t) _array[_index +1])<<8) + _array[_index])
52#define SW18AB_LATEST_FIRMWARE 226
53#define SW08B_LATEST_FIRMWARE 226
54#define SW4B_LATEST_FIRMWARE 203
55
56typedef enum
57{
58 SW_LOW = 0,
62
63
66
87// SW_DATA_SOURCE_PIN_20 = 20,
88// SW_DATA_SOURCE_PIN_21 = 21,
89// SW_DATA_SOURCE_PIN_22 = 22,
90// SW_DATA_SOURCE_PIN_23 = 23,
91// SW_DATA_SOURCE_PIN_24 = 24,
92// SW_DATA_SOURCE_PIN_25 = 25,
93// SW_DATA_SOURCE_PIN_26 = 26,
94// SW_DATA_SOURCE_PIN_27 = 27,
95// SW_DATA_SOURCE_PIN_28 = 28,
96// SW_DATA_SOURCE_PIN_29 = 29,
97// SW_DATA_SOURCE_PIN_30 = 30,
98// SW_DATA_SOURCE_PIN_31 = 31,
99// SW_DATA_SOURCE_PIN_32 = 32,
100// SW_DATA_SOURCE_PIN_33 = 33,
101// SW_DATA_SOURCE_PIN_34 = 34,
102// SW_DATA_SOURCE_PIN_35 = 35,
103// SW_DATA_SOURCE_PIN_36 = 36,
104// SW_DATA_SOURCE_PIN_37 = 37,
105// SW_DATA_SOURCE_PIN_38 = 38,
106// SW_DATA_SOURCE_PIN_39 = 39,
107// SW_DATA_SOURCE_PIN_40 = 40,
108// SW_DATA_SOURCE_PIN_41 = 41,
109// SW_DATA_SOURCE_PIN_42 = 42,
110// SW_DATA_SOURCE_PIN_43 = 43,
111// SW_DATA_SOURCE_PIN_44 = 44,
112// SW_DATA_SOURCE_PIN_45 = 45,
113// SW_DATA_SOURCE_PIN_46 = 46,
114// SW_DATA_SOURCE_PIN_47 = 47,
115// SW_DATA_SOURCE_PIN_48 = 48,
116// SW_DATA_SOURCE_PIN_49 = 49,
117// SW_DATA_SOURCE_PIN_50 = 50,
118// SW_DATA_SOURCE_PIN_51 = 51,
119// SW_DATA_SOURCE_PIN_52 = 52,
120// SW_DATA_SOURCE_PIN_53 = 53,
121// SW_DATA_SOURCE_PIN_54 = 54,
122// SW_DATA_SOURCE_PIN_55 = 55,
123// SW_DATA_SOURCE_PIN_56 = 56,
124// SW_DATA_SOURCE_PIN_57 = 57,
125// SW_DATA_SOURCE_PIN_58 = 58,
126// SW_DATA_SOURCE_PIN_59 = 59,
127// SW_DATA_SOURCE_PIN_60 = 60,
128// SW_DATA_SOURCE_PIN_61 = 61,
129// SW_DATA_SOURCE_PIN_62 = 62,
130// SW_DATA_SOURCE_PIN_63 = 63,
143
154 //NOT ANALOG SW_DATA_SOURCE_PIN_5_MV = 105,
155 //NOT ANALOG SW_DATA_SOURCE_PIN_6_MV = 106,
156 //NOT ANALOG SW_DATA_SOURCE_PIN_7_MV = 107,
157 //NOT ANALOG SW_DATA_SOURCE_PIN_8_MV = 108,
158 //NOT ANALOG SW_DATA_SOURCE_PIN_9_MV = 109,
159 //NOT ANALOG SW_DATA_SOURCE_PIN_10_MV = 110,
160 //NOT ANALOG SW_DATA_SOURCE_PIN_11_MV = 111,
161 //NOT ANALOG SW_DATA_SOURCE_PIN_12_MV = 112,
162 //NOT ANALOG SW_DATA_SOURCE_PIN_13_MV = 113,
163 //NOT ANALOG SW_DATA_SOURCE_PIN_14_MV = 114,
164 //NOT ANALOG SW_DATA_SOURCE_PIN_15_MV = 115,
171// SW_DATA_SOURCE_2HZ_SIN = 166,
174// SW_DATA_SOURCE_1HZ_SIN = 169,
177// SW_DATA_SOURCE_2SEC_SIN = 172,
180// SW_DATA_SOURCE_8SEC_SIN = 175,
183// SW_DATA_SOURCE_65SEC_SIN = 178,
185};
186
187#define ERROR_HOST_INCORRECT_NUMBER_BYTES_WRITTEN 0x10000
188#define ERROR_HOST_DATA_TOO_LONG 0x10001
189#define ERROR_HOST_NACK_ADDRESS 0x10002
190#define ERROR_HOST_NACK_DATA 0x10003
191#define ERROR_HOST_OTHER_I2C_ERROR 0x10004
192
193#define WOMBAT_MAXIMUM_PINS 20
194
196{
197 CMD_ECHO ='!',
200 CMD_RESET = 'R',
256
257};
258
259
302
303class SerialWombatChip;
304
305typedef void (*SerialWombatErrorHandler_t) (uint16_t errorNumber, SerialWombatChip* sw);
306
317{
318private:
319
320 char version[8] = { 0 };
321 HardwareSerial * SerialInstance = NULL;
322 TwoWire* i2cInterface = NULL;
323 uint8_t _pinmode[WOMBAT_MAXIMUM_PINS]={}; // Includes Pullup
324 bool _pullDown[WOMBAT_MAXIMUM_PINS]={};
325 bool _openDrain[WOMBAT_MAXIMUM_PINS]={};
326 bool _highLow[WOMBAT_MAXIMUM_PINS] = {};
327 bool _asleep = false;
328 SerialWombatErrorHandler_t errorHandler = NULL;
329 bool _currentlyCommunicating = false;
330public:
337 uint16_t _supplyVoltagemV = 0;
338
340 uint8_t model[4] = { 0 };
341
343 uint8_t fwVersion[4] = { 0 };
344
350 uint8_t uniqueIdentifier[16];
351
357
363
370 uint16_t errorCount = 0;
371
373 bool inBoot = false;
374
376 int16_t lastErrorCode = 0;
377
386
387 void configureDigitalPin(uint8_t pin, uint8_t highLow)
388 {
389 uint8_t tx[8] = { 200,pin,0,0,0,0,0,0x55 };
390 uint8_t rx[8];
391 switch (_pinmode[pin])
392 {
393 case INPUT: // Arduino input
394 {
395 tx[3] = 2; //Input
396 }
397 break;
398 case OUTPUT:
399 {
400 if (highLow == LOW)
401 {
402 tx[3] = 0;
403 }
404 else if (highLow == HIGH)
405 {
406 tx[3] = 1;
407 }
408 else
409 {
410 return;
411 }
412 }
413 break;
414 case INPUT_PULLUP:
415 {
416 tx[3] = 2; //Input
417 tx[4] = 1; //Pullup on
418 }
419 break;
420 default:
421 {
422 return;
423 }
424 }
425 tx[6] = _openDrain[pin];
426 tx[5] = _pullDown[pin];
427 sendPacket(tx, rx, true);
428 }
429
433 uint32_t sendReadyTime = 0;
434
438 int16_t initialize()
439 {
440 lastErrorCode = 0;
441 readVersion();
445 return(lastErrorCode);
446 }
447
455 {
457 if (version[0] == 'S' && version[1] == '0' && version[2] == '4')
458 { //16F15214
459 for (uint32_t address = 0x8100; address <= 0x8108; ++address)
460 {
461 uint32_t data = readFlashAddress(address);
464 /* Always zero... leave out
465 uniqueIdentifier[uniqueIdentifierLength] = (uint8_t)(data>>8);
466 ++uniqueIdentifierLength;
467 */
468 }
469 }
470 else if (isSW18())
471 {
472 for (uint32_t address = 0x801600; address <= 0x801608; address += 2)
473 {
474 uint32_t data = readFlashAddress(address);
481 }
482 }
483 else if (isSW08())
484 { //CH32V003
485 for (uint32_t address = 0x1FFFF7E8; address <= 0x1FFFF7F0; address += 4)
486 {
487 uint32_t data = readFlashAddress(address);
490 uniqueIdentifier[uniqueIdentifierLength] = (uint8_t)(data >> 8);
492 uniqueIdentifier[uniqueIdentifierLength] = (uint8_t)(data >> 16);
494 uniqueIdentifier[uniqueIdentifierLength] = (uint8_t)(data >> 24);
496 }
497 }
498
499 }
500
507
509 {
510 if (version[0] == 'S' && version[1] == '0' && version[2] == '4')
511 { //16F15214
512
513 uint32_t data = readFlashAddress(0x8006);
514 deviceIdentifier = (uint16_t)data;
515 data = readFlashAddress(0x8005);
516 deviceRevision = (uint16_t)data;
517 }
518 else if (isSW18())
519 {
520 uint32_t data = readFlashAddress(0xFF0000);
521 deviceIdentifier = (uint16_t)data;
522 data = readFlashAddress(0xFF0002);
523 deviceRevision = (uint16_t)data & 0xF;
524 }
525 }
526
532 uint16_t returnErrorCode(uint8_t* rx)
533 {
534 uint16_t result = rx[1] - '0';
535 result *= 10;
536 result += rx[2] - '0';
537 result *= 10;
538 result += rx[3] - '0';
539 result *= 10;
540 result += rx[4] - '0';
541 result *= 10;
542 result += rx[5] - '0';
543 return(result);
544 }
545
546
547
548public:
563 int16_t begin(HardwareSerial& serial, bool reset = true)
564 {
565 SerialInstance = &serial;
566 SerialInstance->begin(115200);
567 SerialInstance->setTimeout(2);
568 SerialInstance->write((uint8_t*)"UUUUUUUU", 8);
569 delay(5);
570 while (SerialInstance->read() >= 0);
571 if (reset)
572 {
574 sendReadyTime = millis() + 1000;
575 return(1);
576 }
577 else
578 {
579 return initialize();
580 }
581
582
583 }
584
594 int16_t begin(uint8_t i2cAddress);
595
609 int16_t begin(TwoWire& wire, uint8_t i2cAddress, bool reset = true)
610 {
611 i2cInterface = &wire;
612 address = i2cAddress;
613
614 Wire.beginTransmission(i2cAddress);
615 int error = Wire.endTransmission();
616
617
618 if (error != 0)
619 {
620 return(-1);
621 }
622
623 if (reset)
624 {
626 sendReadyTime = millis() + 250;
627 return(1);
628 }
629 else
630 {
631 sendReadyTime = 0;
632 return initialize();
633
634 }
635 }
636
638
649 int sendPacket( uint8_t tx[], uint8_t rx[]);
650
660 int sendPacket(uint8_t tx[]);
661
675 int sendPacket(uint8_t tx[], uint8_t rx[], bool retryIfEchoDoesntMatch, uint8_t beginningBytesToMatch = 8, uint8_t endBytesToMatch = 0);
686 int sendPacket(uint8_t tx[], bool retryIfEchoDoesntMatch);
687
696
697 int sendPacketNoResponse(uint8_t tx[]);
698
707 char* readVersion(void)
708 {
709 uint8_t tx[] = { 'V',0x55,0x55,0x55,0x55,0x55,0x55,0x55 };
710 uint8_t rx[8];
711 sendPacket(tx, rx);
712 memcpy(version, &rx[1], 7);
713 version[7] = '\0';
714 memcpy(model, &rx[1], 3);
715 model[3] = '\0';
716 fwVersion[0] = rx[5];
717 fwVersion[1] = rx[6];
718 fwVersion[2] = rx[7];
719 return (version);
720 }
721
728 uint32_t readVersion_uint32(void)
729 {
730 readVersion();
731 return (
732 ((uint32_t)fwVersion[0] - '0') * 100 +
733 ((uint32_t)fwVersion[1] - '0') * 10 +
734 (uint32_t)fwVersion[2] - '0');
735 }
736
742 {
743 uint32_t v = readVersion_uint32();
744 if (isSW18())
745 {
746 //Hack for the irrx release
747 return (v == SW18AB_LATEST_FIRMWARE );
748 }
749 else if (isSW08())
750 {
751 //Hack for the irrx release
752 return (v == SW08B_LATEST_FIRMWARE );
753 }
754 else
755 {
756 return (v == SW4B_LATEST_FIRMWARE);
757
758 }
759 }
760
770 uint16_t readPublicData(uint8_t pin)
771 {
772 uint8_t tx[] = { 0x81,pin,255,255,0x55,0x55,0x55,0x55 };
773 uint8_t rx[8];
774 sendPacket(tx, rx);
775 return(rx[2] + (uint16_t)rx[3] * 256);
776 }
777
788 {
789 return (readPublicData((uint8_t)dataSource));
790 }
791
797 uint16_t writePublicData(uint8_t pin, uint16_t value)
798 {
799 uint8_t tx[] = { 0x82,pin,(uint8_t)(value & 0xFF),(uint8_t)(value >> 8) ,255,0x55,0x55,0x55 };
800 uint8_t rx[8];
801 sendPacket(tx, rx);
802 return (rx[2] + rx[3] * 256);
803 }
804
810 uint16_t writePublicData(uint8_t firstPin, uint16_t firstValue, uint8_t secondPin,uint16_t secondValue)
811 {
812 uint8_t tx[] = { 0x82,firstPin,(uint8_t)(firstValue & 0xFF),(uint8_t)(firstValue >> 8) ,secondPin,(uint8_t)(secondValue & 0xFF),(uint8_t)(secondValue >> 8) ,0x55 };
813 uint8_t rx[8];
814 sendPacket(tx, rx);
815 return (rx[2] + rx[3] * 256);
816 }
817
818 uint32_t comparePublicDataToThreshold(uint16_t threshold = 0)
819 {
820 uint8_t tx[] = { (uint8_t) SerialWombatCommands::COMMAND_BINARY_PIN_POLL_THRESHOLD,SW_LE16(threshold) ,0x55, 0x55,0x55,0x55,0x55 };
821 uint8_t rx[8];
822 sendPacket(tx, rx);
823 return (ARRAY_UINT32(rx,1));
824 }
825
835
836 uint16_t readSupplyVoltage_mV(void)
837 {
838 if (isSW18() || isSW08())
839 {
841 }
842 else
843 {
844 int32_t counts = readPublicData(66); // Get FVR counts (1.024 v)
845 if (counts > 0)
846 {
847 uint32_t mv = 1024 * 65536 / counts;
848 _supplyVoltagemV = (uint16_t)mv;
849 }
850 else
851 {
853 }
854 }
855 return(_supplyVoltagemV);
856 }
857
858
870 {
871 if (isSW18())
872 {
873 int32_t result = readPublicData(70);
874 if (result >= 32768)
875 {
876 result = result - 65536;
877 }
878 return ((int16_t)result);
879 }
880 else
881 {
882 return 2500;
883 }
884 }
885
893 {
894 uint8_t tx[9] = "ReSeT!#*";
896 }
897
906 void pinMode(uint8_t pin, uint8_t mode, bool pullDown = false, bool openDrain = false)
907 {
908 if (pin >= WOMBAT_MAXIMUM_PINS)
909 {
910 return;
911 }
912 _pullDown[pin] = pullDown;
913 _openDrain[pin] = openDrain;
914 _pinmode[pin] = mode;
915 configureDigitalPin(pin, mode);
916 }
917
925 void digitalWrite(uint8_t pin, uint8_t val)
926 {
927 configureDigitalPin(pin, val);
928 }
929
935 int digitalRead(uint8_t pin)
936 {
937 if (readPublicData(pin) > 0)
938 {
939 return (HIGH);
940 }
941 else
942 {
943 return (LOW);
944 }
945 }
946
956 int analogRead(uint8_t pin)
957 {
958 uint8_t tx[] = { 200,pin,PIN_MODE_ANALOGINPUT,0,0,0,0,0 };
959 uint8_t rx[8];
960 sendPacket(tx, rx);
961 return (readPublicData(pin) >> 6); // Scale from 16 bit value to 10 bit value.
962 }
963
975 void analogWrite(uint8_t pin, int val)
976 {
977 uint8_t dutyCycleLow = 0;
978 if (val == 255)
979 {
980 dutyCycleLow = 255;
981 }
982 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_MODE0,pin,PIN_MODE_PWM,pin,dutyCycleLow,(uint8_t) val,false,0x55 };
983 uint8_t rx[8];
984 sendPacket(tx, rx);
985 }
986
998 {
999 uint8_t tx[8] = { 'V',0x55,0x55,0x55,0x55,0x55,0x55,0x55 };
1000 uint8_t rx[8];
1001 sendPacket(tx, rx);
1002 if (rx[0] == 'V' && (rx[1] == 'S' || rx[1] == 'B'))
1003 {
1004 model[0] = rx[1];
1005 model[1] = rx[2];
1006 model[2] = rx[3];
1007 model[3] = 0;
1008 fwVersion[0] = rx[5];
1009 fwVersion[1] = rx[6];
1010 fwVersion[2] = rx[7];
1011 fwVersion[3] = 0;
1012
1013 inBoot = (rx[1] == 'B');
1014 return (true);
1015 }
1016 return (false);
1017 }
1018
1026 {
1027 uint8_t tx[8] = { 0x81,67,68,0x55,0x55,0x55,0x55,0x55 };
1028 uint8_t rx[8];
1029 sendPacket(tx, rx);
1030 uint32_t returnval = rx[2] + (((uint32_t)rx[3]) << 8) + (((uint32_t)rx[4]) << 16) + (((uint32_t)rx[5]) << 24);
1031 return (returnval);
1032 }
1033
1041
1043 {
1044 return readPublicData(69);
1045 }
1046
1057 {
1058 uint8_t tx[] = "BoOtLoAd";
1059 sendPacket(tx);
1060 }
1061
1082 uint8_t readRamAddress(uint16_t address)
1083 {
1084 uint8_t tx[8] = { 0xA0,SW_LE16(address),0x55,0x55,0x55,0x55,0x55 };
1085 uint8_t rx[8];
1086 sendPacket(tx, rx);
1087 return(rx[3]);
1088 }
1089
1109
1110 int16_t writeRamAddress(uint16_t address, uint8_t value)
1111 {
1112 uint8_t tx[8] = { 0xA3,SW_LE16(address),0,0,value,0x55,0x55};
1113 return sendPacket(tx);
1114 }
1115
1130
1131 uint32_t readFlashAddress(uint32_t address)
1132 {
1133 uint8_t tx[8] = { 0xA1,SW_LE32(address),0x55,0x55,0x55 };
1134 uint8_t rx[8];
1135 sendPacket(tx, rx);
1136 return(((uint32_t)rx[4]) + (((uint32_t)rx[5]) <<8) + (((uint32_t)rx[6]) <<16) + (((uint32_t)rx[7]) <<24));
1137 }
1138
1150 int16_t readUserBuffer(uint16_t index, uint8_t* buffer, uint16_t count)
1151 {
1152 uint16_t bytesRead = 0;
1153 while (bytesRead < count)
1154 {
1155 byte tx[] = {(byte)SerialWombatCommands::COMMAND_BINARY_READ_USER_BUFFER, (byte)(index & 0xFF), (byte)(index >> 8), 0x55, 0x55, 0x55, 0x55, 0x55};
1156 byte rx[8];
1157 int16_t result = sendPacket(tx, rx);
1158 if (result >= 0)
1159 {
1160 for (int i = 1; i < 8; ++i)
1161 {
1162 buffer[bytesRead] = rx[i];
1163 ++bytesRead;
1164 ++index;
1165 if (bytesRead >= count)
1166 {
1167 break;
1168 }
1169 }
1170 }
1171 else
1172 {
1173 return (bytesRead);
1174 }
1175 }
1176 return (bytesRead);
1177 }
1178
1190 void sleep4B()
1191 {
1192 uint8_t tx[8] = { 'S','l','E','e','P','!','#','*'};
1193 sendPacket(tx);
1194 _asleep = true;
1195 }
1196
1215 void sleep8B(uint16_t delay)
1216 {
1217 uint8_t tx[8] = { 'S','l','E','e','P','!',SW_LE16(delay)};
1218
1219 sendPacket(tx);
1220 _asleep = true;
1221 }
1222
1224 void wake()
1225 {
1226 uint8_t tx[8] = { '!','!','!','!','!','!','!','!' };
1227 sendPacket(tx);
1228 }
1229
1231 bool isSW04()
1232 {
1233 return ( model[1] == '0' && model[2] == '4');
1234 }
1235
1236
1238 bool isSW18()
1239 {
1240 return ( model[1] == '1' && model[2] == '8');
1241 }
1242
1243 bool isSW08()
1244 {
1245 return ( model[1] == '0' && model[2] == '8');
1246 }
1247
1257 {
1258 if (isSW08())
1259 {
1260 for (uint32_t address = 0x08003F00; address < 0x08003FC0; address += 4)
1261 {
1262 uint32_t flashData = readFlashAddress(address);
1263 if (flashData != 0xFFFFFFFF)
1264 {
1265 return true;
1266 }
1267 }
1268 return false;
1269 }
1270 else if (isSW18())
1271 {
1272 // TODO: Implement startup command detection for Serial Wombat 18AB.
1273 return false;
1274 }
1275 return false;
1276 }
1277
1284 bool isPinModeSupported(int pinMode, bool supressErrorReporting = true)
1285 {
1286 SerialWombatErrorHandler_t tempErrorHandler = errorHandler;
1287 if (supressErrorReporting)
1288 {
1290 }
1292 registerErrorHandler(tempErrorHandler);
1293
1294 return result;
1295 }
1296
1302 {
1303 if (isSW04())
1304 {
1305 switch (pinMode)
1306 {
1307 case PIN_MODE_DIGITALIO:
1310 case PIN_MODE_SERVO:
1311 case PIN_MODE_PWM:
1312 case PIN_MODE_DEBOUNCE:
1314 case PIN_MODE_WATCHDOG:
1317 return true;
1318
1319 default:
1320 return false;
1321 }
1322 }
1323
1324 uint8_t tx[8] = {(uint8_t)SerialWombatCommands::CONFIGURE_CHANNEL_MODE_CHECK_MODE_SUPPORTED, 1, (uint8_t)pinMode, 0x55, 0x55, 0x55, 0x55, 0x55};
1325 int16_t returnVal = sendPacket(tx);
1326 returnVal *= -1;
1327 return (returnVal != SW_ERROR_UNKNOWN_PIN_MODE);
1328 }
1329
1330
1331
1332
1334 int16_t eraseFlashPage(uint32_t address)
1335 {
1336 uint8_t tx[8] = { (uint8_t)SerialWombatCommands::COMMAND_BINARY_WRITE_FLASH,
1337 0, //Erase Page
1339 0x55,0x55 };
1340 #ifdef ESP32 // ESP32 times out early, even if you set the I2C timeout command.
1342 delay(40);
1343 return(8);
1344#else
1345 return sendPacket(tx);
1346 #endif
1347 }
1348
1349
1351 int16_t writeFlashRow(uint32_t address)
1352 {
1353 uint8_t tx[8] = { (uint8_t)SerialWombatCommands::COMMAND_BINARY_WRITE_FLASH,
1354 1, // Write entire row
1355 SW_LE32(address),0x55,0x55 };
1356#ifdef ESP32
1357 return sendPacketNoResponse(tx);
1358
1359#else
1360 return sendPacket(tx);
1361#endif
1362 }
1363
1364
1365
1366
1376 int16_t setThroughputPin(uint8_t pin)
1377 {
1378 uint8_t tx[8] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_MODE0,pin,PIN_MODE_FRAME_TIMER,0x55,0x55,0x55,0x55,0x55 };
1379 return sendPacket(tx);
1380 }
1381
1395 int16_t setThroughputPin(uint32_t address)
1396 {
1397 uint8_t tx[8] = { (uint8_t)SerialWombatCommands::COMMAND_BINARY_SET_ADDRESS,SW_LE32(address),0x55,0x55,0x55 };
1398 return sendPacket(tx);
1399 }
1400
1408 int writeUserBuffer(uint16_t index, uint8_t* buffer, uint16_t count)
1409 {
1410 uint16_t bytesSent = 0;
1411 if (count == 0)
1412 {
1413 return 0;
1414 }
1415
1416 { // Send first packet of up to 4 bytes
1417 uint8_t bytesToSend = 4;
1418 if (count < 4)
1419 {
1420 bytesToSend = (uint8_t)count;
1421 count = 0;
1422 }
1423 else
1424 {
1425 count -= 4;
1426 }
1427
1428 uint8_t tx[8] = { 0x84,SW_LE16(index), bytesToSend,0x55,0x55,0x55,0x55 };
1429 uint8_t rx[8];
1430
1431 uint8_t i;
1432 for (i = 0; i < bytesToSend; ++i)
1433 {
1434 tx[4 + i] = buffer[i];
1435 }
1436 int result = sendPacket(tx, rx);
1437 if (rx[0] == 'E')
1438 {
1439 return (result);
1440 }
1441 bytesSent = bytesToSend;
1442 }
1443 while (count >= 7) // Continue sending
1444 {
1445
1446 count -= 7;
1447 uint8_t tx[8] = { 0x85,0x55,0x55,0x55,0x55,0x55,0x55,0x55 };
1448 uint8_t rx[8];
1449 uint8_t i;
1450 for (i = 0; i < 7; ++i)
1451 {
1452 tx[1 + i] = buffer[bytesSent + i];
1453 }
1454 int result = sendPacket(tx, rx);
1455 if (rx[0] == 'E')
1456 {
1457 return (result);
1458 }
1459 bytesSent += 7;
1460 }
1461 while (count > 0)
1462 {
1463
1464 { // Send first packet of up to 4 bytes
1465 uint8_t bytesToSend = 4;
1466 if (count < 4)
1467 {
1468 bytesToSend = (uint8_t)count;
1469 count = 0;
1470 }
1471 else
1472 {
1473 count -= 4;
1474 }
1475
1476 uint8_t tx[8] = { 0x84,SW_LE16(index + bytesSent), bytesToSend,0x55,0x55,0x55,0x55 };
1477 uint8_t rx[8];
1478
1479 uint8_t i;
1480 for (i = 0; i < bytesToSend; ++i)
1481 {
1482 tx[4 + i] = buffer[i + bytesSent];
1483 }
1484 int result = sendPacket(tx, rx);
1485 if (rx[0] == 'E')
1486 {
1487 return (result);
1488 }
1489 bytesSent += bytesToSend;
1490 }
1491 }
1492 return(bytesSent);
1493
1494
1495 }
1496
1503 int writeUserBuffer(uint16_t index, char* s)
1504 {
1505 return writeUserBuffer(index, (uint8_t*)s, (uint16_t)strlen(s));
1506 }
1507
1514 int writeUserBuffer(uint16_t index, const char s[])
1515 {
1516 return writeUserBuffer(index, (uint8_t*)s, (uint16_t)strlen(s));
1517 }
1518
1519
1520
1532 int16_t writeFrameTimerPin(uint8_t pin)
1533{
1534 uint8_t tx[] = { 0xC8 ,pin,(uint8_t)PIN_MODE_FRAME_TIMER,0x55,0x55,0x55,0x55,0x55 };
1535 return sendPacket(tx);
1536}
1537
1538
1546 static uint8_t find(bool keepTrying = false)
1547 {
1548 do
1549 {
1550 for (int i2cAddress = 0x60; i2cAddress <= 0x6F; ++i2cAddress)
1551 {
1552 Wire.beginTransmission(i2cAddress);
1553 int error = Wire.endTransmission();
1554
1555
1556 if (error == 0)
1557 {
1558 uint8_t tx[8] = { 'V',0x55,0x55,0x55,0x55,0x55,0x55,0x55 };
1559 uint8_t rx[8];
1560 Wire.beginTransmission(i2cAddress);
1561 Wire.write(tx, 8);
1562 Wire.endTransmission();
1563 Wire.requestFrom((uint8_t)i2cAddress, (uint8_t)8);
1564
1565 int count = 0;
1566 while (Wire.available() && count < 8)
1567 {
1568 rx[count] = Wire.read();
1569 ++count;
1570 }
1571 if (count == 8)
1572 {
1573 if (rx[0] == 'V' && (rx[1] == 'S' || rx[1]=='B'))
1574 {
1575 return(i2cAddress); // Found one.
1576 }
1577 }
1578 }
1579 }
1580 delay(0);
1581 }while (keepTrying);
1582 return(0); // Didn't find one.
1583 }
1584
1585
1592 int16_t readLastErrorCommand(uint8_t* cmd)
1593{
1594
1595 uint8_t tx[8] = { (uint8_t)SerialWombatCommands::COMMAND_READ_LAST_ERROR_PACKET, 0,0x55,0x55,0x55,0x55,0x55,0x55 };
1596 uint8_t rx[8];
1597 if (sendPacket(tx, rx) >= 0)
1598 {
1599 for (int i = 1; i < 8; ++i)
1600 {
1601 cmd[i - 1] = rx[i];
1602 }
1603 }
1604 else
1605 {
1606 return (lastErrorCode);
1607 }
1608 tx[1] = 7;
1609 if (sendPacket(tx, rx) >= 0)
1610 {
1611 cmd[7] = rx[1];
1612 }
1613 return(lastErrorCode);
1614}
1615
1621 {
1622 errorHandler = handler;
1623 }
1624
1626 uint8_t address = 0;
1627
1630
1637 int16_t echo(uint8_t data[], uint8_t count = 7)
1638 {
1639 uint8_t tx[] = "!UUUUUUU";
1640 for (int i = 0; i < 7 && i < count; ++i)
1641 {
1642 tx[i + 1] = (uint8_t)data[i];
1643 }
1644 return sendPacket(tx);
1645 }
1646
1652
1653 int16_t echo(char* data)
1654 {
1655 int length = strlen(data);
1656 uint8_t tx[] = "!UUUUUUU";
1657 for (int i = 0; i < 7 && i < length; ++i)
1658 {
1659 tx[i + 1] = (uint8_t)data[i];
1660 }
1661 return sendPacket(tx);
1662 }
1663
1668 uint32_t readBirthday()
1669 {
1670 if (isSW18())
1671 {
1672 uint32_t birthday = (readFlashAddress(0x2A00C) >> 8) & 0xFF;
1673 birthday *= 100;
1674 birthday += (readFlashAddress(0x2A00C)) & 0xFF;
1675 birthday *= 100;
1676 birthday += readFlashAddress(0x2A00E) & 0xFF;
1677 birthday *= 100;
1678 birthday += readFlashAddress(0x2A010) & 0xFF;
1679 return (birthday);
1680 }
1681 return 0;
1682 }
1683
1688 int16_t readBrand(char* data)
1689 {
1690 uint8_t length = 0;
1691 if (isSW18())
1692 {
1693 for (int i = 0; i < 32; ++i)
1694 {
1695 uint32_t val = readFlashAddress(0x2A020 + i * 2) ;
1696 if ((val & 0xFF) != 0xFF)
1697 {
1698 data[i ] = (char)(val & 0xFF);
1699 ++length;
1700 }
1701 else
1702 {
1703 data[length] = 0;
1704 return (length);
1705 }
1706 }
1707 data[length] = 0;
1708 return (length);
1709 }
1710
1711 data[0] = 0;
1712 return 0 ;
1713 }
1714
1715};
1716
1731{
1732private:
1733 SerialWombatChip& _sw;
1734 uint32_t lastMillis = 0;
1735 uint32_t lastFrames = 0;
1736public:
1741 SerialWombat18ABOscillatorTuner(SerialWombatChip& serialWombatChip) : _sw(serialWombatChip) { }
1742
1746 void update() {
1747 uint32_t m = millis();
1748 if (lastMillis == 0)
1749 {
1750 lastMillis = m;
1751 uint32_t frames = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_MSW);
1752 uint16_t frameslsb = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_LSW);
1753 if (frames != _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_MSW))
1754 {
1755 frameslsb = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_LSW);
1756 frames = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_MSW);
1757 }
1758 frames <<= 16;
1759 frames += frameslsb;
1760 lastFrames = frames;
1761
1762 }
1763 else if ((m - lastMillis) < 10000)
1764 {
1765 //Do nothing
1766 }
1767 else if (m < lastMillis)
1768 {
1769 //Has it been 47 days already?
1770 lastMillis = 0;
1771 }
1772 else
1773 {
1774 uint32_t diff = m - lastMillis;
1775
1776 uint32_t frames = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_MSW);
1777 uint16_t frameslsb = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_LSW);
1778
1779 if (frames != _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_MSW))
1780 {
1781 frameslsb = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_LSW);
1782 frames = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_MSW);
1783 }
1784 frames <<= 16;
1785 frames += frameslsb;
1786 uint32_t framesDif = frames - lastFrames;
1787
1788 if (diff > framesDif )
1789 {
1790 // Running slow
1791 uint8_t tx[] = { (uint8_t)SerialWombatCommands::COMMAND_ADJUST_FREQUENCY,
1792 SW_LE16(1),//Counts to increment
1793 SW_LE16(0), // Counts to decrement
1794 0x55,0x55,0x55};
1795 _sw.sendPacket(tx);
1796 }
1797 else if (diff < framesDif)
1798 {
1799 // Running mfast
1800 uint8_t tx[] = { (uint8_t)SerialWombatCommands::COMMAND_ADJUST_FREQUENCY,
1801 SW_LE16(0),//Counts to increment
1802 SW_LE16(1), // Counts to decrement
1803 0x55,0x55,0x55 };
1804 _sw.sendPacket(tx);
1805
1806 }
1807
1808 lastMillis = m;
1809 lastFrames = frames;
1810
1811 }
1812
1813 }
1814
1815};
1816
1817
1831{
1832private:
1833 SerialWombatChip& _sw;
1834 uint32_t lastMillis = 0;
1835 uint32_t lastFrames = 0;
1836
1837 // CH32V003 RCC_CTLR low byte. The Serial Wombat 8B firmware RAM read/write
1838 // commands use 16-bit addresses for memory-mapped register access.
1839 static const uint16_t CH32V003_RCC_CTLR_LOW = 0x1000;
1840 static const uint8_t CH32V003_HSITRIM_MASK = 0xF8;
1841 static const uint8_t CH32V003_HSITRIM_SHIFT = 3;
1842
1843 uint8_t readTrim()
1844 {
1845 return ((_sw.readRamAddress(CH32V003_RCC_CTLR_LOW) & CH32V003_HSITRIM_MASK) >> CH32V003_HSITRIM_SHIFT);
1846 }
1847
1848 void writeTrim(uint8_t trim)
1849 {
1850 uint8_t rccCtlrLow = _sw.readRamAddress(CH32V003_RCC_CTLR_LOW);
1851 rccCtlrLow &= ~CH32V003_HSITRIM_MASK;
1852 rccCtlrLow |= (uint8_t)((trim & 0x1F) << CH32V003_HSITRIM_SHIFT);
1853 _sw.writeRamAddress(CH32V003_RCC_CTLR_LOW, rccCtlrLow);
1854 }
1855
1856public:
1861 SerialWombat8BOscillatorTuner(SerialWombatChip& serialWombatChip) : _sw(serialWombatChip) { }
1862
1866 void update() {
1867 uint32_t m = millis();
1868 if (lastMillis == 0)
1869 {
1870 lastMillis = m;
1871 uint32_t frames = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_MSW);
1872 uint16_t frameslsb = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_LSW);
1873 if (frames != _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_MSW))
1874 {
1875 frameslsb = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_LSW);
1876 frames = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_MSW);
1877 }
1878 frames <<= 16;
1879 frames += frameslsb;
1880 lastFrames = frames;
1881
1882 }
1883 else if ((m - lastMillis) < 10000)
1884 {
1885 //Do nothing
1886 }
1887 else if (m < lastMillis)
1888 {
1889 //Has it been 47 days already?
1890 lastMillis = 0;
1891 }
1892 else
1893 {
1894 uint32_t diff = m - lastMillis;
1895
1896 uint32_t frames = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_MSW);
1897 uint16_t frameslsb = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_LSW);
1898
1899 if (frames != _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_MSW))
1900 {
1901 frameslsb = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_LSW);
1902 frames = _sw.readPublicData(SerialWombatDataSource::SW_DATA_SOURCE_FRAMES_RUN_MSW);
1903 }
1904 frames <<= 16;
1905 frames += frameslsb;
1906 uint32_t framesDif = frames - lastFrames;
1907
1908 if (diff > framesDif )
1909 {
1910 // Running slow
1911 uint8_t trim = readTrim();
1912 if (trim < 31)
1913 {
1914 writeTrim(trim + 1);
1915 }
1916 }
1917 else if (diff < framesDif)
1918 {
1919 // Running fast
1920 uint8_t trim = readTrim();
1921 if (trim > 0)
1922 {
1923 writeTrim(trim - 1);
1924 }
1925
1926 }
1927
1928 lastMillis = m;
1929 lastFrames = frames;
1930
1931 }
1932
1933 }
1934
1935};
1936
1937/*
1938End of cross platform code synchronization. Random string to help the compare tool sync lines:
1939asdkj38vjn1nasdnvuwlamafdjiivnowalskive
1940*/
1941
1944
1945
1946
1947
1948
1957
1966
1967#include "SerialWombatPin.h"
1968#include "SerialWombatQueue.h"
1973#include "SerialWombatBlink.h"
1974#include "SerialWombat18CapTouch.h"
1975#include "SerialWombat18ABVGA.h"
1982#include "SerialWombatHBridge.h"
1983#include "SerialWombatHSClock.h"
1984#include "SerialWombatHSCounter.h"
1985#include "SerialWombatIRRx.h"
1986#include "SerialWombatIRTx.h"
1993#include "SerialWombatPulseTimer.h"
1994#include "SerialWombatPWM.h"
1995#include "SerialWombatQuadEnc.h"
1999#include "SerialWombatServo.h"
2000#include "SerialWombatSPI.h"
2001#include "SerialWombatTM1637.h"
2002#include "SerialWombatUART.h"
2004#include "SerialWombatWatchdog.h"
2005#include "SerialWombatWS2812.h"
2007#include "PCB0030_Bridge.h"
2008#include "PCB0031_Grip.h"
2009#include "PCB0041_Remcon.h"
2010#include "PCB0042_LSD.h"
2011#include "PCB0046_HSD.h"
2012#include "PCB0048_Mux.h"
2013
2014#endif
#define INPUT
#define SW18AB_LATEST_FIRMWARE
#define WOMBAT_MAXIMUM_PINS
void SerialWombatSerialErrorHandlerBrief(uint16_t error, SerialWombatChip *sw)
a sample error handler that can be registered with registerErrorHandler to report protocol errors on ...
#define SW_LE16(_a)
Convert a uint16_t to two bytes in little endian format for array initialization.
SerialWombatCommands
@ COMMAND_CAPTURE_STARTUP_SEQUENCE
(0xB6)
@ COMMAND_BINARY_WRITE_FLASH
(0xA4)
@ COMMAND_BINARY_READ_USER_BUFFER
(0x83)
@ COMMAND_BINARY_QUEUE_INFORMATION
(0x94)
@ COMMAND_BINARY_QUEUE_INITIALIZE
(0x90)
@ COMMAND_BINARY_SET_PIN_BUFFFER
(0x82)
@ COMMAND_ENABLE_2ND_UART
(0xA6)
@ COMMAND_UART1_RX_7BYTES
(0xB3)
@ COMMAND_ADJUST_FREQUENCY
(0xB7)
@ COMMAND_BINARY_WRITE_USER_BUFFER
(0x84)
@ CONFIGURE_PIN_MODE_DISABLE
(219)
@ COMMAND_BINARY_QUEUE_CLONE
(0x95)
@ COMMAND_BINARY_QUEUE_ADD_BYTES
(0x91)
@ COMMAND_BINARY_READ_EEPROM
(0xA2)
@ COMMAND_BINARY_QUEUE_ADD_7BYTES
(0x92)
@ COMMAND_UART0_TX_7BYTES
(0xB0)
@ COMMAND_BINARY_QUEUE_READ_BYTES
(0x93)
@ COMMAND_BINARY_SET_ADDRESS
(0xB9)
@ CONFIGURE_PIN_INPUTPROCESS
(211)
@ CONFIGURE_CHANNEL_MODE_CHECK_MODE_SUPPORTED
(218)
@ COMMAND_BINARY_WRITE_USER_BUFFER_CONTINUE
(0x85)
@ COMMAND_BINARY_CONFIG_DATALOGGER
(0x96)
@ COMMAND_UART1_TX_7BYTES
(0xB2)
@ COMMAND_UART0_RX_7BYTES
(0xB1)
@ COMMAND_BINARY_RW_PIN_MEMORY
(0xB5)
@ COMMAND_READ_LAST_ERROR_PACKET
(0xA7)
@ COMMAND_BINARY_WRITE_RAM
(0xA3)
@ COMMAND_BINARY_READ_RAM
(0xA0)
@ COMMAND_BINARY_TEST_SEQUENCE
(0xB4)
@ CONFIGURE_CHANNEL_MODE_HW_2
(222)
@ COMMAND_BINARY_READ_PIN_BUFFFER
(0x81)
@ CONFIGURE_CHANNEL_MODE_HW_1
(221)
@ COMMAND_BINARY_READ_FLASH
(0xA1)
@ CONFIGURE_CHANNEL_MODE_HW_3
(223)
@ COMMAND_CALIBRATE_ANALOG
(0xA5)
@ COMMAND_BINARY_PIN_POLL_THRESHOLD
(0x8F)
@ COMMAND_BINARY_CONFIGURE
(0x9F)
#define SW08B_LATEST_FIRMWARE
#define SW_LE32(_a)
Convert a uint32_t to four bytes in little endian format for array initialization.
#define SW4B_LATEST_FIRMWARE
SerialWombatPinMode_t
@ PIN_MODE_PULSE_ON_CHANGE
(25)
@ PIN_MODE_CHARLIEPLEX
(43)
@ PIN_MODE_FRAME_TIMER
(21)
@ PIN_MODE_UNKNOWN
(0xFF)
@ PIN_MODE_TM1637
(11)
@ PIN_MODE_PULSETIMER
(18)
@ PIN_MODE_PS2KEYBOARD
(32)
@ PIN_MODE_FREQUENCY_OUTPUT
(36)
@ PIN_MODE_HS_SERVO
(26)
@ PIN_MODE_CONTROLLED
(1)
@ PIN_MODE_RANDOMBLINK
(42)
@ PIN_MODE_QUEUED_PULSE_OUTPUT
(34)
@ PIN_MODE_HBRIDGE
(6)
@ PIN_MODE_SW18AB_CAPTOUCH
(22)
@ PIN_MODE_LIQUIDCRYSTAL
(28)
@ PIN_MODE_IRRX
(37)
@ PIN_MODE_QUADRATUREENCODER
(5)
@ PIN_MODE_UART_RX_TX
(17)
@ PIN_MODE_WATCHDOG
(7)
@ PIN_MODE_HS_COUNTER
< (29)
@ PIN_MODE_PROTECTED_OUTPUT
(8)
@ PIN_MODE_ANALOGINPUT
(2)
@ PIN_MODE_UART1_RX_TX
(23)
@ PIN_MODE_I2C_CONTROLLER
(33)
@ PIN_MODE_PWM
(16)
@ PIN_MODE_RESISTANCEINPUT
(24)
@ PIN_MODE_DEBOUNCE
(10)
@ PIN_MODE_BLINK
(40)
@ PIN_MODE_INPUT_PROCESSOR
(14)
@ PIN_MODE_ULTRASONIC_DISTANCE
(27)
@ PIN_MODE_HS_CLOCK
@ PIN_MODE_SERVO
(3)
@ PIN_MODE_DIGITALIO
(0)
@ PIN_MODE_THROUGHPUT_CONSUMER
(4)
@ PIN_MODE_MATRIX_KEYPAD
(15)
@ PIN_MODE_SW_UART
(13)
@ PIN_MODE_SPI
(41)
@ PIN_MODE_IRTX
(38)
@ PIN_MODE_VGA
(31)
@ PIN_MODE_WS2812
(12)
void SerialWombatSerialErrorHandlerVerbose(uint16_t error, SerialWombatChip *sw)
a sample error handler that can be registered with registerErrorHandler to report protocol errors on ...
SerialWombatDataSource
A list of Serial Wombat public data sources.
@ SW_DATA_SOURCE_PIN_10
(10) 16 bit public data provided by Pin 10
@ SW_DATA_SOURCE_VBG_COUNTS_VS_VREF
(76) A/D conversion of VBG against VRef . Used for mfg calibration
@ SW_DATA_SOURCE_PIN_5
(5) 16 bit public data provided by Pin 5
@ SW_DATA_SOURCE_PIN_14
(14) 16 bit public data provided by Pin 14
@ SW_DATA_SOURCE_PIN_13
(13) 16 bit public data provided by Pin 13
@ SW_DATA_SOURCE_1024mvCounts
(66) The number of ADC counts that result from a 1.024V reading
@ SW_DATA_SOURCE_TEMPERATURE
(70)The internal core temperature expressed in 100ths deg C
@ SW_DATA_SOURCE_PIN_1
(1) 16 bit public data provided by Pin 1
@ SW_DATA_SOURCE_FRAMES_RUN_LSW
(67) The number of frames run since reset, least significant 16 bits
@ SW_DATA_SOURCE_VCC_mVOLTS
(75) The system source voltage in mV
@ SW_DATA_SOURCE_PIN_11
(11) 16 bit public data provided by Pin 11
@ SW_DATA_SOURCE_8SEC_SAW
(174)Sawtooth wave that goes from 0 to 65535 to 0 every 8192 frames
@ SW_DATA_SOURCE_PIN_4_MV
(104) Pin 4 public output expressed in mV (for analog modes only)
@ SW_DATA_SOURCE_PIN_6
(6) 16 bit public data provided by Pin 6
@ SW_DATA_SOURCE_PIN_15
(15) 16 bit public data provided by Pin 15
@ SW_DATA_SOURCE_LFSR
A Linear FeedBack Shift register (32,7,5,3,2,1) based pseudo-random number generator.
@ SW_DATA_SOURCE_OVERRUN_FRAMES
(69) The number of frames that ran more than 1mS
@ SW_DATA_SOURCE_PIN_9
(9) 16 bit public data provided by Pin 9
@ SW_DATA_SOURCE_PIN_12
(12) 16 bit public data provided by Pin 12
@ SW_DATA_SOURCE_PIN_3_MV
(103) Pin 3 public output expressed in mV (for analog modes only)
@ SW_DATA_SOURCE_PIN_8
(8) 16 bit public data provided by Pin 8
@ SW_DATA_SOURCE_PIN_18
(18) 16 bit public data provided by Pin 18
@ SW_DATA_SOURCE_8SEC_SQUARE
(173)Square wave that alternates between 0 and 65535 every 4096 frames
@ SW_DATA_SOURCE_0x55
(85) 0x55 is a reserved value for resyncing. Returns 0x55 0x55
@ SW_DATA_SOURCE_RESET_REGISTER
Hardware dependent reset reason register contents.
@ SW_DATA_SOURCE_2SEC_SQUARE
(170)Square wave that alternates between 0 and 65535 every 1024 frames
@ SW_DATA_COM_ADDRESS_LOW
The Communications Address of the Device (Lower 16 bits)
@ SW_DATA_SOURCE_PIN_18_MV
(118) Pin 18 public output expressed in mV (for analog modes only)
@ SW_DATA_COM_ADDRESS_HIGH
The Communications Address of the Device (HIGHER 16 bits) Anticipated for CAN ID.
@ SW_DATA_SOURCE_ERRORS
(72)The number of incoming packets that have caused errors since reset (rolls over at 65535)
@ SW_DATA_SOURCE_PIN_0_MV
(100) Pin 0 public output expressed in mV (for analog modes only)
@ SW_DATA_SOURCE_PIN_4
(4) 16 bit public data provided by Pin 4
@ SW_DATA_SOURCE_SYSTEM_UTILIZATION
(74) A number between 0 and 65535 that scales to the average length of pin processing frames between ...
@ SW_DATA_SOURCE_PACKETS_RECEIVED
(71) The nubmer of incoming command packets that have been processed since reset (rolls over at 65535...
@ SW_DATA_SOURCE_1HZ_SQUARE
(167) Square wave that alternates between 0 and 65535 every 512 frames
@ SW_DATA_SOURCE_2SEC_SAW
(171)Sawtooth wave that goes from 0 to 65535 to 0 every 2048 frames
@ SW_DATA_SOURCE_PIN_17_MV
(117) Pin 17 public output expressed in mV (for analog modes only)
@ SW_DATA_SOURCE_PIN_1_MV
(101) Pin 1 public output expressed in mV (for analog modes only)
@ SW_DATA_SOURCE_DROPPED_FRAMES
(73) The number of times since reset that a frame ran so far behind that it crossed two subsequent 1m...
@ SW_DATA_SOURCE_PIN_16_MV
(116) Pin 16 public output expressed in mV (for analog modes only)
@ SW_DATA_SOURCE_PIN_0
(0) 16 bit public data provided by Pin 0
@ SW_DATA_SOURCE_PIN_2
(2) 16 bit public data provided by Pin 2
@ SW_DATA_SOURCE_PIN_2_MV
(102) Pin 2 public output expressed in mV (for analog modes only)
@ SW_DATA_SOURCE_PIN_16
(16) 16 bit public data provided by Pin 16
@ SW_DATA_SOURCE_1HZ_SAW
(168) Sawtooth wave that goes from 0 to 65535 to 0 every 1024 frames
@ SW_DATA_SOURCE_PIN_19_MV
(119) Pin 19 public output expressed in mV (for analog modes only)
@ SW_DATA_SOURCE_PIN_7
(7) 16 bit public data provided by Pin 7
@ SW_DATA_SOURCE_FRAMES_RUN_MSW
(68) The number of frames run since reset, most significant 16 bits
@ SW_DATA_SOURCE_INCREMENTING_NUMBER
(65) An number that increments each time it is accessed.
@ SW_DATA_SOURCE_PIN_19
(19) 16 bit public data provided by Pin 19
@ SW_DATA_SOURCE_2HZ_SAW
(165) Sawtooth wave that goes from 0 to 65535 to 0 every 512 frames
@ SW_DATA_SOURCE_PIN_17
(17) 16 bit public data provided by Pin 17
@ SW_DATA_SOURCE_PIN_3
(3) 16 bit public data provided by Pin 3
@ SW_DATA_SOURCE_65SEC_SAW
(177 )Sawtooth wave that goes from 0 to 65535 to 0 every 65536 frames
@ SW_DATA_SOURCE_NONE
(255 ) Used to mean "No Source Selected"
@ SW_DATA_SOURCE_2HZ_SQUARE
(164) Square wave that alternates between 0 and 65535 every 256 frames
@ SW_DATA_SOURCE_65SEC_SQUARE
(176) Square wave that alternates between 0 and 65535 every 32768 frames
#define ARRAY_UINT32(_array, _index)
void(* SerialWombatErrorHandler_t)(uint16_t errorNumber, SerialWombatChip *sw)
SerialWombatPinState_t
@ SW_INPUT
@ SW_HIGH
@ SW_LOW
@ SW_ERROR_UNKNOWN_PIN_MODE
(#3) A Pin mode was indicated that is not avaialble on this model or version of Serial Wombat chip
SerialWombat18ABOscillatorTuner(SerialWombatChip &serialWombatChip)
Class constructor for SerialWombat18OscillatorTuner.
void update()
Call periodically to tune the SW18AB oscillator to reported millis.
void update()
Call periodically to tune the SW8B oscillator to reported millis.
SerialWombat8BOscillatorTuner(SerialWombatChip &serialWombatChip)
Class constructor for SerialWombat8BOscillatorTuner.
Class for a Serial Wombat chip. Each Serial Wombat chip on a project should have its own instance.
int16_t setThroughputPin(uint32_t address)
Set this chip Address (SW8B only)
uint8_t uniqueIdentifier[16]
bool isLatestFirmware(void)
Check if the firmware is the latest version (or more precisely, if the firmware matches this verison ...
uint8_t address
The I2C address of the SerialWombatChip instance.
uint16_t deviceRevision
void wake()
Called to send a dummy packet to the Serial Wombat 8B chip to wake it from sleep and ready it for oth...
uint32_t sendReadyTime
Used as a countdown after a reset command is issued.
uint8_t uniqueIdentifierLength
bool isSW04()
Returns true if the instance received a model number corresponding to the Serial Wombat 18 series of ...
uint32_t comparePublicDataToThreshold(uint16_t threshold=0)
int16_t echo(uint8_t data[], uint8_t count=7)
Echo a byte array back to the host. Used for testing and debugging.
void digitalWrite(uint8_t pin, uint8_t val)
Set an output pin High or Low.
uint32_t readFlashAddress(uint32_t address)
Read Address from Flash based on 32 bit address.
bool inBoot
Set to true if boot mode is indicated by a version query.
bool isPinModeSupported(SerialWombatPinMode_t pinMode)
Check if a specific pin mode is supported by the firmware in the Serial Wombat chip....
bool isSW08()
Returns true if the instance received a model number corresponding to the Serial Wombat 08 series of ...
void readUniqueIdentifier()
Read the unique identifier from the Serial Wombat chip and store it in uniqueIdentifier.
char * readVersion(void)
Request version string (combined model and firmware) and return pointer to it.
void configureDigitalPin(uint8_t pin, uint8_t highLow)
Configure a pin to a digital state with the same parameters as Arduino's digitalWrite() function.
uint16_t readPublicData(uint8_t pin)
Read the 16 Bit public data associated with a Serial Wombat Pin Mode.
bool isConfiguredWithStartupCommands()
Returns true if startup commands have been configured in the Serial Wombat chip.
uint8_t fwVersion[4]
Contains the last firmware Version retreived by queryVersion() as a zero-terminated string.
uint32_t readBirthday()
Read the birthday of the Serial Wombat 18AB chip.
uint8_t communicationErrorRetries
How many times to retry a packet if communcation bus (such as I2C) error.
int16_t echo(char *data)
Echo a byte array back to the host. Used for testing and debugging.
uint16_t readOverflowFrames()
Get the number of times an overflow Frame has occured.
static uint8_t find(bool keepTrying=false)
Search the I2C Bus addresses 0x68 to 0x6F for I2C devices, and test to see if they respond to Serial ...
uint16_t writePublicData(uint8_t firstPin, uint16_t firstValue, uint8_t secondPin, uint16_t secondValue)
Write a 16 bit value to a Serial Wombat pin Mode.
void readDeviceIdentifier()
Read the device identifier from the Serial Wombat chip and store it in deviceIdentifier.
int writeUserBuffer(uint16_t index, uint8_t *buffer, uint16_t count)
Write bytes to the User Memory Buffer in the Serial Wombat chip.
int16_t readTemperature_100thsDegC(void)
Measure the Serial Wombat chip's internal temperature.
int sendPacketNoResponse(uint8_t tx[])
Send an 8 byte packet to the Serial Wombat chip, don't wait for a response.
uint8_t readRamAddress(uint16_t address)
Read Address from RAM based on 16 bit address.
int16_t readUserBuffer(uint16_t index, uint8_t *buffer, uint16_t count)
Read data from the Serial Wombat 18AB's internal RAM buffer.
bool isSW18()
Returns true if the instance received a model number corresponding to the Serial Wombat 18 series of ...
int16_t lastErrorCode
The last error code returned as part of a protocol error message expressed as a positive integer.
int16_t readBrand(char *data)
Read the brand of the Serial Wombat 18AB chip.
void pinMode(uint8_t pin, uint8_t mode, bool pullDown=false, bool openDrain=false)
Set a pin to INPUT or OUTPUT, with options for pull Ups and open Drain settings.
int16_t setThroughputPin(uint8_t pin)
Set a pin to be a throughput monitoring pin.
int16_t begin(HardwareSerial &serial, bool reset=true)
initialize a Serial Wombat chip to use a Serial Interface.
int sendPacket(uint8_t tx[], uint8_t rx[])
Send an 8 byte packet to the Serial Wombat chip and wait for 8 bytes back.
void sleep4B()
Shuts down most functions of the Serial Wombat 4B chip reducing power consumption.
uint32_t readVersion_uint32(void)
Request version as a uint32.
uint16_t writePublicData(uint8_t pin, uint16_t value)
Write a 16 bit value to a Serial Wombat pin Mode.
uint16_t readSupplyVoltage_mV(void)
Measure the Serial Wombat chip's Supply voltage.
int16_t writeFlashRow(uint32_t address)
Writes a row in flash. Intended for use with the Bootloader, not by end users outside of bootloading ...
int writeUserBuffer(uint16_t index, char *s)
Write bytes to the User Memory Buffer in the Serial Wombat chip.
int16_t eraseFlashPage(uint32_t address)
Erases a page in flash. Intended for use with the Bootloader, not by end users outside of bootloading...
uint16_t returnErrorCode(uint8_t *rx)
Convert an ASCII Error code from a received packet into an integer error code.
uint16_t deviceIdentifier
int16_t writeRamAddress(uint16_t address, uint8_t value)
Write byte to Address in RAM based on 16 bit address.
int16_t initialize()
An internal function used to set up the Serial Wombat chip and this class. Call begin() instead of th...
bool isPinModeSupported(int pinMode, bool supressErrorReporting=true)
Check if a specific pin mode is supported by the firmware in the Serial Wombat chip....
int16_t writeFrameTimerPin(uint8_t pin)
Set a pin to be a frame timer for system utilization (SW18AB Only)
uint16_t _supplyVoltagemV
void registerErrorHandler(SerialWombatErrorHandler_t handler)
Registers an error handler that is called by the SerialWombatChip sendPacket() command when a protoco...
int16_t begin(TwoWire &wire, uint8_t i2cAddress, bool reset=true)
initialize a Serial Wombat chip to use a specified I2C Interface and address.
void analogWrite(uint8_t pin, int val)
Set a pin to PWM output.
void sleep8B(uint16_t delay)
Shuts down the Serial Wombat 8B chip reducing power consumption as low as 10uA.
uint16_t errorCount
Incremented every time a communication or command error is detected.
int writeUserBuffer(uint16_t index, const char s[])
Write bytes to the User Memory Buffer in the Serial Wombat chip.
int analogRead(uint8_t pin)
Configures pin as analog input and does an immediate A/D conversion.
uint16_t readPublicData(SerialWombatDataSource dataSource)
Read the 16 Bit public data associated with a Serial Wombat Pin Mode.
bool queryVersion()
Send a version request to the Serial Wombat chip.
void jumpToBoot()
Jump to Bootloader and wait for a UART download of new firmware.
int digitalRead(uint8_t pin)
Reads the state of a Pin.
void hardwareReset()
Send a reset command to the Serial Wombat chip.
uint8_t model[4]
Contains the last model retreived by queryVersion() as a zero-terminated string.
uint32_t readFramesExecuted()
Get the number of 1mS frames that have been executed since Serial Wombat chip reset.
int16_t readLastErrorCommand(uint8_t *cmd)
Returns the last Serial Wombat command that produced a protocol error.
This class name is depricated. Do not use for new development. Use SerialWombatChip instead.