diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5dbfeeead..21c9a1e5c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,15 @@
### Development versions after 0.10.0 release
+#### Build 2005220
+
+- Added TPM2.NET protocol support (need to set WLED broadcast UDP port to 65506)
+- Added TPM2 protocol support via Serial
+- Support up to 6553 seconds preset cycle durations (backend, NOT yet in UI)
+- Merged pull request #591 fixing WS2801 color order
+- Merged pull request #858 adding fully featured travis builds
+- Merged pull request #862 adding DMX proxy feature
+
#### Build 2005100
- Update to Espalexa v2.4.6 (+1.6kB free heap memory)
diff --git a/wled00/data/index.htm b/wled00/data/index.htm
index 9bf3de6b3..163512c3f 100644
--- a/wled00/data/index.htm
+++ b/wled00/data/index.htm
@@ -927,7 +927,7 @@ input[type=number]::-webkit-outer-spin-button {
First preset:
Last preset:
- Time per preset: s
+ Time per preset: s
Transition: s
diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h
index 2d8401bc8..feb4cf2bd 100644
--- a/wled00/fcn_declare.h
+++ b/wled00/fcn_declare.h
@@ -77,7 +77,6 @@ void handleIR();
#include "src/dependencies/json/ArduinoJson-v6.h"
#include "src/dependencies/json/AsyncJson-v6.h"
#include "FX.h"
-// TODO: AsynicWebServerRequest conflict?
void deserializeSegment(JsonObject elem, byte it);
bool deserializeState(JsonObject root);
diff --git a/wled00/json.cpp b/wled00/json.cpp
index 86a875abf..e70a41ad5 100644
--- a/wled00/json.cpp
+++ b/wled00/json.cpp
@@ -315,7 +315,7 @@ void serializeInfo(JsonObject root)
case REALTIME_MODE_UDP: root["lm"] = "UDP"; break;
case REALTIME_MODE_HYPERION: root["lm"] = "Hyperion"; break;
case REALTIME_MODE_E131: root["lm"] = "E1.31"; break;
- case REALTIME_MODE_ADALIGHT: root["lm"] = F("USB Adalight");
+ case REALTIME_MODE_ADALIGHT: root["lm"] = F("USB Adalight/TPM2");
case REALTIME_MODE_ARTNET: root["lm"] = "Art-Net"; break;
case REALTIME_MODE_TPM2NET: root["lm"] = F("tpm2.net"); break;
}
diff --git a/wled00/udp.cpp b/wled00/udp.cpp
index 91426e912..0a3f2d788 100644
--- a/wled00/udp.cpp
+++ b/wled00/udp.cpp
@@ -223,24 +223,24 @@ void handleNotifications()
if (tpmType == 0xaa) { //TPM2.NET polling, expect answer
sendTPM2Ack(); return;
}
- if (tpmType == 0xda) { //TPM2.NET data
- realtimeIP = notifierUdp.remoteIP();
- realtimeLock(realtimeTimeoutMs, REALTIME_MODE_TPM2NET);
- if (realtimeOverride) return;
+ if (tpmType != 0xda) return; //return if notTPM2.NET data
- uint16_t frameSize = (udpIn[2] << 8) + udpIn[3];
- byte packetNum = udpIn[4]; //starts with 1!
- byte numPackets = udpIn[5];
+ realtimeIP = notifierUdp.remoteIP();
+ realtimeLock(realtimeTimeoutMs, REALTIME_MODE_TPM2NET);
+ if (realtimeOverride) return;
- uint16_t id = tpmDataReceived / 3; //start LED
- for (uint16_t i = 6; i < frameSize + 4; i += 3)
- {
- setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
- id++; if (id >= ledCount) break;
- }
- tpmDataReceived += frameSize;
- if (packetNum == numPackets) {strip.show(); tpmDataReceived = 0;} //show if last packet
+ uint16_t frameSize = (udpIn[2] << 8) + udpIn[3];
+ byte packetNum = udpIn[4]; //starts with 1!
+ byte numPackets = udpIn[5];
+
+ uint16_t id = ((tpmFirstFrameSize/3)*(packetNum-1)) / 3; //start LED
+ for (uint16_t i = 6; i < frameSize + 4; i += 3)
+ {
+ setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
+ id++; if (id >= ledCount) break;
}
+ if (packetNum == 1) tpmFirstFrameSize = frameSize;
+ if (packetNum == numPackets) {strip.show(); } //show if last packet
}
//UDP realtime: 1 warls 2 drgb 3 drgbw
diff --git a/wled00/wled.h b/wled00/wled.h
index a98b2bd54..9f2d56118 100644
--- a/wled00/wled.h
+++ b/wled00/wled.h
@@ -8,7 +8,7 @@
*/
// version code in format yymmddb (b = daily build)
-#define VERSION 2005180
+#define VERSION 2005220
// ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS).
@@ -426,7 +426,7 @@ WLED_GLOBAL byte realtimeMode _INIT(REALTIME_MODE_INACTIVE);
WLED_GLOBAL byte realtimeOverride _INIT(REALTIME_OVERRIDE_NONE);
WLED_GLOBAL IPAddress realtimeIP _INIT((0, 0, 0, 0));
WLED_GLOBAL unsigned long realtimeTimeout _INIT(0);
-WLED_GLOBAL uint16_t tpmDataReceived _INIT(0);
+WLED_GLOBAL uint16_t tpmFirstFrameSize _INIT(0);
// mqtt
WLED_GLOBAL long lastMqttReconnectAttempt _INIT(0);
diff --git a/wled00/wled_serial.cpp b/wled00/wled_serial.cpp
index aa89b7135..75ace2b25 100644
--- a/wled00/wled_serial.cpp
+++ b/wled00/wled_serial.cpp
@@ -1,7 +1,7 @@
#include "wled.h"
/*
- * Adalight handler
+ * Adalight and TPM2 handler
*/
enum class AdaState {
@@ -13,7 +13,10 @@ enum class AdaState {
Header_CountCheck,
Data_Red,
Data_Green,
- Data_Blue
+ Data_Blue,
+ TPM2_Header_Type,
+ TPM2_Header_CountHi,
+ TPM2_Header_CountLo
};
void handleSerial()
@@ -33,6 +36,9 @@ void handleSerial()
switch (state) {
case AdaState::Header_A:
if (next == 'A') state = AdaState::Header_d;
+ else if (next == 0x9C) { //TPM2 start byte
+ state = AdaState::TPM2_Header_Type;
+ }
break;
case AdaState::Header_d:
if (next == 'd') state = AdaState::Header_a;
@@ -57,6 +63,20 @@ void handleSerial()
if (check == next) state = AdaState::Data_Red;
else state = AdaState::Header_A;
break;
+ case AdaState::TPM2_Header_Type:
+ state = AdaState::Header_A; //(unsupported) TPM2 command or invalid type
+ if (next == 0xDA) state = AdaState::TPM2_Header_CountHi; //TPM2 data
+ else if (next == 0xAA) Serial.write(0xAC); //TPM2 ping
+ break;
+ case AdaState::TPM2_Header_CountHi:
+ pixel = 0;
+ count = (next * 0x100) /3;
+ state = AdaState::TPM2_Header_CountLo;
+ break;
+ case AdaState::TPM2_Header_CountLo:
+ count += next /3 + 1;
+ state = AdaState::Data_Red;
+ break;
case AdaState::Data_Red:
red = next;
state = AdaState::Data_Green;