145 lines
6.5 KiB
C++
145 lines
6.5 KiB
C++
#include "wled.h"
|
|
|
|
/*
|
|
* E1.31 handler
|
|
*/
|
|
|
|
void handleE131Packet(e131_packet_t* p, IPAddress clientIP){
|
|
//E1.31 protocol support
|
|
|
|
uint16_t uni = htons(p->universe);
|
|
uint8_t previousUniverses = uni - e131Universe;
|
|
uint16_t possibleLEDsInCurrentUniverse;
|
|
uint16_t dmxChannels = htons(p->property_value_count) -1;
|
|
|
|
// only listen for universes we're handling & allocated memory
|
|
if (uni >= (e131Universe + E131_MAX_UNIVERSE_COUNT)) return;
|
|
|
|
if (e131SkipOutOfSequence)
|
|
if (p->sequence_number < e131LastSequenceNumber[uni-e131Universe] && p->sequence_number > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){
|
|
DEBUG_PRINT("skipping E1.31 frame (last seq=");
|
|
DEBUG_PRINT(e131LastSequenceNumber[uni-e131Universe]);
|
|
DEBUG_PRINT(", current seq=");
|
|
DEBUG_PRINT(p->sequence_number);
|
|
DEBUG_PRINT(", universe=");
|
|
DEBUG_PRINT(uni);
|
|
DEBUG_PRINTLN(")");
|
|
return;
|
|
}
|
|
e131LastSequenceNumber[uni-e131Universe] = p->sequence_number;
|
|
|
|
// update status info
|
|
realtimeIP = clientIP;
|
|
|
|
switch (DMXMode) {
|
|
case DMX_MODE_DISABLED:
|
|
return; // nothing to do
|
|
break;
|
|
|
|
case DMX_MODE_SINGLE_RGB:
|
|
if (uni != e131Universe) return;
|
|
if (dmxChannels-DMXAddress+1 < 3) return;
|
|
arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131);
|
|
for (uint16_t i = 0; i < ledCount; i++)
|
|
setRealtimePixel(i, p->property_values[DMXAddress+0], p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], 0);
|
|
break;
|
|
|
|
case DMX_MODE_SINGLE_DRGB:
|
|
if (uni != e131Universe) return;
|
|
if (dmxChannels-DMXAddress+1 < 4) return;
|
|
arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131);
|
|
if (DMXOldDimmer != p->property_values[DMXAddress+0]) {
|
|
DMXOldDimmer = p->property_values[DMXAddress+0];
|
|
bri = p->property_values[DMXAddress+0];
|
|
strip.setBrightness(bri);
|
|
}
|
|
for (uint16_t i = 0; i < ledCount; i++)
|
|
setRealtimePixel(i, p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], p->property_values[DMXAddress+3], 0);
|
|
break;
|
|
|
|
case DMX_MODE_EFFECT:
|
|
if (uni != e131Universe) return;
|
|
if (dmxChannels-DMXAddress+1 < 11) return;
|
|
if (DMXOldDimmer != p->property_values[DMXAddress+0]) {
|
|
DMXOldDimmer = p->property_values[DMXAddress+0];
|
|
bri = p->property_values[DMXAddress+0];
|
|
}
|
|
if (p->property_values[DMXAddress+1] < MODE_COUNT)
|
|
effectCurrent = p->property_values[DMXAddress+ 1];
|
|
effectSpeed = p->property_values[DMXAddress+ 2]; // flickers
|
|
effectIntensity = p->property_values[DMXAddress+ 3];
|
|
effectPalette = p->property_values[DMXAddress+ 4];
|
|
col[0] = p->property_values[DMXAddress+ 5];
|
|
col[1] = p->property_values[DMXAddress+ 6];
|
|
col[2] = p->property_values[DMXAddress+ 7];
|
|
colSec[0] = p->property_values[DMXAddress+ 8];
|
|
colSec[1] = p->property_values[DMXAddress+ 9];
|
|
colSec[2] = p->property_values[DMXAddress+10];
|
|
if (dmxChannels-DMXAddress+1 > 11)
|
|
{
|
|
col[3] = p->property_values[DMXAddress+11]; //white
|
|
colSec[3] = p->property_values[DMXAddress+12];
|
|
}
|
|
transitionDelayTemp = 0; // act fast
|
|
colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); // don't send UDP
|
|
return; // don't activate realtime live mode
|
|
break;
|
|
|
|
case DMX_MODE_MULTIPLE_RGB:
|
|
arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131);
|
|
if (previousUniverses == 0) {
|
|
// first universe of this fixture
|
|
possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress + 1) / 3;
|
|
for (uint16_t i = 0; i < ledCount; i++) {
|
|
if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
|
setRealtimePixel(i, p->property_values[DMXAddress+i*3+0], p->property_values[DMXAddress+i*3+1], p->property_values[DMXAddress+i*3+2], 0);
|
|
}
|
|
} else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) {
|
|
// additional universe(s) of this fixture
|
|
uint16_t numberOfLEDsInPreviousUniverses = ((512 - DMXAddress + 1) / 3); // first universe
|
|
if (previousUniverses > 1) numberOfLEDsInPreviousUniverses += (512 / 3) * (previousUniverses - 1); // extended universe(s) before current
|
|
possibleLEDsInCurrentUniverse = dmxChannels / 3;
|
|
for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) {
|
|
uint8_t j = i - numberOfLEDsInPreviousUniverses;
|
|
if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
|
setRealtimePixel(i, p->property_values[j*3+1], p->property_values[j*3+2], p->property_values[j*3+3], 0);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DMX_MODE_MULTIPLE_DRGB:
|
|
arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131);
|
|
if (previousUniverses == 0) {
|
|
// first universe of this fixture
|
|
if (DMXOldDimmer != p->property_values[DMXAddress+0]) {
|
|
DMXOldDimmer = p->property_values[DMXAddress+0];
|
|
bri = p->property_values[DMXAddress+0];
|
|
strip.setBrightness(bri);
|
|
}
|
|
possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress) / 3;
|
|
for (uint16_t i = 0; i < ledCount; i++) {
|
|
if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
|
setRealtimePixel(i, p->property_values[DMXAddress+i*3+1], p->property_values[DMXAddress+i*3+2], p->property_values[DMXAddress+i*3+3], 0);
|
|
}
|
|
} else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) {
|
|
// additional universe(s) of this fixture
|
|
uint16_t numberOfLEDsInPreviousUniverses = ((512 - DMXAddress + 1) / 3); // first universe
|
|
if (previousUniverses > 1) numberOfLEDsInPreviousUniverses += (512 / 3) * (previousUniverses - 1); // extended universe(s) before current
|
|
possibleLEDsInCurrentUniverse = dmxChannels / 3;
|
|
for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) {
|
|
uint8_t j = i - numberOfLEDsInPreviousUniverses;
|
|
if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s)
|
|
setRealtimePixel(i, p->property_values[j*3+1], p->property_values[j*3+2], p->property_values[j*3+3], 0);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
DEBUG_PRINTLN("unknown E1.31 DMX mode");
|
|
return; // nothing to do
|
|
break;
|
|
}
|
|
|
|
e131NewData = true;
|
|
}
|