Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DMX on RMT fix for picky fixtures. #730

Merged
merged 11 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ESPixelStick/src/ESPixelStick.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#define MicroSecondsInASecond (MicroSecondsInAmilliSecond * MilliSecondsInASecond)
#define NanoSecondsInAMicroSecond 1000
#define NanoSecondsInASecond (MicroSecondsInASecond * NanoSecondsInAMicroSecond)
#define NanoSecondsInAMilliSecond (NanoSecondsInAMicroSecond * MicroSecondsInAmilliSecond)

#define CPU_ClockTimeNS ((1.0 / float(F_CPU)) * float(NanoSecondsInASecond))

Expand Down
2 changes: 2 additions & 0 deletions ESPixelStick/src/GPIO_Defs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ typedef enum
# include "platformDefinitions/GPIO_Defs_ESP32_QUINLED_UNO_ETH_ESPSV3.hpp"
#elif defined (BOARD_ESP32_TTGO_T8)
# include "platformDefinitions/GPIO_Defs_ESP32_TTGO_T8.hpp"
#elif defined (BOARD_ESP32_BONG69)
# include "platformDefinitions/GPIO_Defs_ESP32_Bong69.hpp"
#elif defined (BOARD_ESP32_WT32ETH01)
# include "platformDefinitions/GPIO_Defs_ESP32_WT32ETH01.hpp"
#elif defined (BOARD_ESP32_WT32ETH01_WASATCH)
Expand Down
27 changes: 15 additions & 12 deletions ESPixelStick/src/input/InputArtnet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@ void c_InputArtnet::GetStatus (JsonObject & jsonStatus)
// DEBUG_START;

JsonObject ArtnetStatus = jsonStatus.createNestedObject (F ("Artnet"));
ArtnetStatus[CN_unifirst] = startUniverse;
ArtnetStatus[CN_unilast] = LastUniverse;
ArtnetStatus[CN_unifirst] = startUniverse;
ArtnetStatus[CN_unilast] = LastUniverse;
ArtnetStatus[CN_unichanlim] = ChannelsPerUniverse;
// DEBUG_V ("");

ArtnetStatus[F ("lastData")] = lastData;
ArtnetStatus[CN_num_packets] = num_packets;
ArtnetStatus[F ("lastData")] = lastData;
ArtnetStatus[CN_num_packets] = num_packets;
ArtnetStatus[CN_packet_errors] = packet_errors;
ArtnetStatus[CN_last_clientIP] = LastRemoteIP.toString ();

Expand Down Expand Up @@ -126,7 +126,7 @@ void c_InputArtnet::Process ()

//-----------------------------------------------------------------------------
void c_InputArtnet::onDmxFrame (uint16_t CurrentUniverseId,
uint32_t length,
uint32_t length,
uint8_t SequenceNumber,
uint8_t * data,
IPAddress remoteIP)
Expand All @@ -143,9 +143,16 @@ void c_InputArtnet::onDmxFrame (uint16_t CurrentUniverseId,
// Do we need to update a sequnce error?
if (SequenceNumber != CurrentUniverse.SequenceNumber)
{
CurrentUniverse.SequenceErrorCounter++;
// DEBUG_V(String(" CurrentUniverseId: ") + String(CurrentUniverseId));
// DEBUG_V(String(" SequenceNumber: ") + String(SequenceNumber));
// DEBUG_V(String("CurrentUniverse.SequenceNumber: ") + String(CurrentUniverse.SequenceNumber));
CurrentUniverse.SequenceNumber = SequenceNumber;
++packet_errors;
// some systems always send a zero sequence number so we ignore the error in that case.
if(0 != SequenceNumber)
{
CurrentUniverse.SequenceErrorCounter++;
++packet_errors;
}
}

++CurrentUniverse.SequenceNumber;
Expand All @@ -158,11 +165,7 @@ void c_InputArtnet::onDmxFrame (uint16_t CurrentUniverseId,
OutputMgr.WriteChannelData( CurrentUniverse.DestinationOffset,
min(CurrentUniverse.BytesToCopy, length),
&data[CurrentUniverse.SourceDataOffset]);
/*
memcpy(CurrentUniverse.Destination,
&data[CurrentUniverse.SourceDataOffset],
min(CurrentUniverse.BytesToCopy, length));
*/

InputMgr.RestartBlankTimer (GetInputChannelId ());
}
else
Expand Down
6 changes: 3 additions & 3 deletions ESPixelStick/src/input/InputArtnet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ class c_InputArtnet : public c_InputCommon

/// JSON configuration parameters
uint16_t startUniverse = 1; ///< Universe to listen for
uint16_t LastUniverse = 1; ///< Last Universe to listen for
uint16_t LastUniverse = 1; ///< Last Universe to listen for
uint16_t ChannelsPerUniverse = 512; ///< Universe boundary limit
uint16_t FirstUniverseChannelOffset = 1; ///< Channel to start listening at - 1 based
uint32_t num_packets = 0;
uint32_t packet_errors = 0;
IPAddress LastRemoteIP;
uint32_t num_packets = 0;
uint32_t packet_errors = 0;

uint8_t lastData = 255;

Expand Down
2 changes: 1 addition & 1 deletion ESPixelStick/src/output/OutputSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ void c_OutputSerial::SetFrameDurration ()
float TotalIntensitiesPerFrame = float(Num_Channels + 1) + SerialHeaderSize + SerialFooterSize;
float TotalBitsPerFrame = float(NumBitsPerIntensity) * TotalIntensitiesPerFrame;
ActualFrameDurationMicroSec = uint32_t(IntensityBitTimeInUs * TotalBitsPerFrame) + InterFrameGapInMicroSec;
FrameDurationInMicroSec = max(uint32_t(25000), ActualFrameDurationMicroSec);
FrameDurationInMicroSec = max(uint32_t(25000), ActualFrameDurationMicroSec);

// DEBUG_V (String (" CurrentBaudrate: ") + String (CurrentBaudrate));
// DEBUG_V (String (" IntensityBitTimeInUs: ") + String (IntensityBitTimeInUs));
Expand Down
59 changes: 41 additions & 18 deletions ESPixelStick/src/output/OutputSerialRmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ void c_OutputSerialRmt::Begin ()
c_OutputRmt::OutputRmtConfig_t OutputRmtConfig;
OutputRmtConfig.RmtChannelId = rmt_channel_t(OutputChannelId);
OutputRmtConfig.DataPin = gpio_num_t(DataPin);
OutputRmtConfig.idle_level = rmt_idle_level_t::RMT_IDLE_LEVEL_HIGH;
OutputRmtConfig.idle_level = rmt_idle_level_t::RMT_IDLE_LEVEL_LOW;
OutputRmtConfig.pSerialDataSource = this;
OutputRmtConfig.SendInterIntensityBits = true;
OutputRmtConfig.SendEndOfFrameBits = true;
Expand Down Expand Up @@ -96,58 +96,80 @@ void c_OutputSerialRmt::SetUpRmtBitTimes()
rmt_item32_t BitValue;

float BitTimeNS = (1.0 / float(CurrentBaudrate)) * NanoSecondsInASecond;
uint32_t BitTimeRmtTicks = uint32_t(BitTimeNS / RMT_TickLengthNS) + 1;
uint32_t OneBitTimeInRmtTicks = uint32_t(BitTimeNS / RMT_TickLengthNS) + 1;
// DEBUG_V(String(" CurrentBaudrate: ") + String(CurrentBaudrate));
// DEBUG_V(String(" BitTimeNS: ") + String(BitTimeNS));
// DEBUG_V(String("RMT_TickLengthNS: ") + String(RMT_TickLengthNS));
// DEBUG_V(String(" BitTimeRmtTicks: ") + String(BitTimeRmtTicks));

BitValue.duration0 = BitTimeRmtTicks;
BitValue.duration0 = OneBitTimeInRmtTicks;
BitValue.level0 = 1;
BitValue.duration1 = BitTimeRmtTicks;
BitValue.duration1 = OneBitTimeInRmtTicks;
BitValue.level1 = 1;
Rmt.SetIntensity2Rmt(BitValue, c_OutputRmt::RmtDataBitIdType_t::RMT_INTERFRAME_GAP_ID);

BitValue.duration0 = BitTimeRmtTicks / 2;
BitValue.duration0 = OneBitTimeInRmtTicks / 2;
BitValue.level0 = 0;
BitValue.duration1 = BitTimeRmtTicks / 2;
BitValue.duration1 = OneBitTimeInRmtTicks / 2;
BitValue.level1 = 0;
Rmt.SetIntensity2Rmt(BitValue, c_OutputRmt::RmtDataBitIdType_t::RMT_STARTBIT_ID);

// ISR will process two bits at a time. This updates the bit durration based on baudrate
BitValue.duration0 = BitTimeRmtTicks / 2;
BitValue.duration0 = OneBitTimeInRmtTicks / 2;
BitValue.level0 = 0;
BitValue.duration1 = BitTimeRmtTicks / 2;
BitValue.duration1 = OneBitTimeInRmtTicks / 2;
BitValue.level1 = 0;
Rmt.SetIntensity2Rmt(BitValue, c_OutputRmt::RmtDataBitIdType_t::RMT_DATA_BIT_ZERO_ID);

BitValue.duration0 = BitTimeRmtTicks / 2;
BitValue.duration0 = OneBitTimeInRmtTicks / 2;
BitValue.level0 = 1;
BitValue.duration1 = BitTimeRmtTicks / 2;
BitValue.duration1 = OneBitTimeInRmtTicks / 2;
BitValue.level1 = 1;
Rmt.SetIntensity2Rmt(BitValue, c_OutputRmt::RmtDataBitIdType_t::RMT_DATA_BIT_ONE_ID);

BitValue.duration0 = BitTimeRmtTicks;
BitValue.duration0 = OneBitTimeInRmtTicks;
BitValue.level0 = 1;
BitValue.duration1 = BitTimeRmtTicks;
BitValue.duration1 = OneBitTimeInRmtTicks;
BitValue.level1 = 0;
Rmt.SetIntensity2Rmt(BitValue, c_OutputRmt::RmtDataBitIdType_t::RMT_DATA_BIT_TWO_ID);

BitValue.duration0 = BitTimeRmtTicks;
BitValue.duration0 = OneBitTimeInRmtTicks;
BitValue.level0 = 1;
BitValue.duration1 = BitTimeRmtTicks;
BitValue.duration1 = OneBitTimeInRmtTicks;
BitValue.level1 = 1;
Rmt.SetIntensity2Rmt(BitValue, c_OutputRmt::RmtDataBitIdType_t::RMT_DATA_BIT_THREE_ID);

BitValue.duration0 = BitTimeRmtTicks * 2; // Two stop bits
BitValue.duration0 = OneBitTimeInRmtTicks * 2; // Two stop bits
BitValue.level0 = 1;
BitValue.duration1 = BitTimeRmtTicks; // one start bit
BitValue.duration1 = OneBitTimeInRmtTicks; // one start bit
BitValue.level1 = 0;
Rmt.SetIntensity2Rmt(BitValue, c_OutputRmt::RmtDataBitIdType_t::RMT_STOP_START_BIT_ID);

BitValue.duration0 = BitTimeRmtTicks;
// max number of bits per 25ms frame
float NanoSecsPerFrame = 25.0 * NanoSecondsInAMilliSecond;
float MaxBitsPerFrame = float(NanoSecsPerFrame / BitTimeNS);
// number of bits used in frame
float NumBitsUsedInFrame = OutputBufferSize * (1.0 + 8.0 + 2.0);
// number of unused frame bits
float NumUnusedBitsInFrame = MaxBitsPerFrame - NumBitsUsedInFrame;

if(NumBitsUsedInFrame >= MaxBitsPerFrame)
{
// frame is bigger than min frame size set minimum idle time
NumUnusedBitsInFrame = 40;
}
float NumUnusedRmtTicksInFrame = min(float(65535.0), (OneBitTimeInRmtTicks * NumUnusedBitsInFrame));
// DEBUG_V(String(" NanoSecsPerFrame: ") + String(NanoSecsPerFrame));
// DEBUG_V(String(" MaxBitsPerFrame: ") + String(MaxBitsPerFrame));
// DEBUG_V(String(" NumBitsUsedInFrame: ") + String(NumBitsUsedInFrame));
// DEBUG_V(String(" NumUnusedBitsInFrame: ") + String(NumUnusedBitsInFrame));
// DEBUG_V(String(" OneBitTimeInRmtTicks: ") + String(OneBitTimeInRmtTicks));
// DEBUG_V(String("NumUnusedRmtTicksInFrame: ") + String(OneBitTimeInRmtTicks * NumUnusedBitsInFrame));
// DEBUG_V(String("NumUnusedRmtTicksInFrame: ") + String(NumUnusedRmtTicksInFrame));

BitValue.duration0 = uint16_t(NumUnusedRmtTicksInFrame/2.0);
BitValue.level0 = 1;
BitValue.duration1 = BitTimeRmtTicks;
BitValue.duration1 = uint16_t(NumUnusedRmtTicksInFrame/2.0);
BitValue.level1 = 1;
Rmt.SetIntensity2Rmt(BitValue, c_OutputRmt::RmtDataBitIdType_t::RMT_END_OF_FRAME);

Expand Down Expand Up @@ -177,6 +199,7 @@ void c_OutputSerialRmt::SetOutputBufferSize(uint32_t NumChannelsAvailable)
// DEBUG_START;

c_OutputSerial::SetOutputBufferSize (NumChannelsAvailable);
SetUpRmtBitTimes();

// DEBUG_END;

Expand Down
93 changes: 93 additions & 0 deletions ESPixelStick/src/platformDefinitions/GPIO_Defs_ESP32_Bong69.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#pragma once
/*
* GPIO_Defs_ESP32_Bongo69.hpp - Output Management class
*
* Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver
* Copyright (c) 2021 Shelby Merrick
* http://www.forkineye.com
*
* This program is provided free for you to use in any way that you wish,
* subject to the laws and regulations where you are using it. Due diligence
* is strongly suggested before using this code. Please give credit where due.
*
* The Author makes no warranty of any kind, express or implied, with regard
* to this program or the documentation contained in this document. The
* Author shall not be liable in any event for incidental or consequential
* damages in connection with, or arising out of, the furnishing, performance
* or use of these programs.
*
*/

#define SUPPORT_ETHERNET

//Output Manager
#define DEFAULT_RMT_0_GPIO gpio_num_t::GPIO_NUM_1
#define DEFAULT_RMT_1_GPIO gpio_num_t::GPIO_NUM_2
#define DEFAULT_RMT_2_GPIO gpio_num_t::GPIO_NUM_3
#define DEFAULT_RMT_3_GPIO gpio_num_t::GPIO_NUM_4
#define DEFAULT_RMT_4_GPIO gpio_num_t::GPIO_NUM_5
#define DEFAULT_RMT_5_GPIO gpio_num_t::GPIO_NUM_12
#define DEFAULT_RMT_6_GPIO gpio_num_t::GPIO_NUM_14
#define DEFAULT_RMT_7_GPIO gpio_num_t::GPIO_NUM_15

// # define SUPPORT_SPI_OUTPUT
// #define DEFAULT_SPI_DATA_GPIO gpio_num_t::GPIO_NUM_15
// #define DEFAULT_SPI_CLOCK_GPIO gpio_num_t::GPIO_NUM_25

#define DEFAULT_I2C_SDA gpio_num_t::GPIO_NUM_21
#define DEFAULT_I2C_SCL gpio_num_t::GPIO_NUM_22

// File Manager
// #define SUPPORT_SD
#define SD_CARD_MISO_PIN gpio_num_t::GPIO_NUM_12
#define SD_CARD_MOSI_PIN gpio_num_t::GPIO_NUM_13
#define SD_CARD_CLK_PIN gpio_num_t::GPIO_NUM_14
#define SD_CARD_CS_PIN gpio_num_t::GPIO_NUM_15

#include <ETH.h>


/*
* ETH_CLOCK_GPIO0_IN - default: external clock from crystal oscillator
* ETH_CLOCK_GPIO0_OUT - 50MHz clock from internal APLL output on GPIO0 - possibly an inverter is needed for LAN8720
* ETH_CLOCK_GPIO16_OUT - 50MHz clock from internal APLL output on GPIO16 - possibly an inverter is needed for LAN8720
* ETH_CLOCK_GPIO17_OUT - 50MHz clock from internal APLL inverted output on GPIO17 - tested with LAN8720
*/
#define DEFAULT_ETH_CLK_MODE eth_clock_mode_t::ETH_CLOCK_GPIO17_OUT

// Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
#define DEFAULT_ETH_POWER_PIN gpio_num_t::GPIO_NUM_16
#define ETH_POWER_PIN DEFAULT_ETH_POWER_PIN
#define DEFAULT_ETH_POWER_PIN_ACTIVE HIGH

// Type of the Ethernet PHY (LAN8720 or TLK110)
#define DEFAULT_ETH_TYPE eth_phy_type_t::ETH_PHY_LAN8720

// I2C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)
#define ETH_ADDR_PHY_LAN8720 1

#define DEFAULT_ETH_ADDR ETH_ADDR_PHY_LAN8720
#define DEFAULT_ETH_TXEN gpio_num_t::GPIO_NUM_21
#define DEFAULT_ETH_TXD0 gpio_num_t::GPIO_NUM_19
#define DEFAULT_ETH_TXD1 gpio_num_t::GPIO_NUM_22
#define DEFAULT_ETH_CRSDV gpio_num_t::GPIO_NUM_27
#define DEFAULT_ETH_RXD0 gpio_num_t::GPIO_NUM_25
#define DEFAULT_ETH_RXD1 gpio_num_t::GPIO_NUM_26
#define DEFAULT_ETH_MDC_PIN gpio_num_t::GPIO_NUM_23
#define DEFAULT_ETH_MDIO_PIN gpio_num_t::GPIO_NUM_18

// Output Types
// Not Finished - #define SUPPORT_OutputType_TLS3001
// #define SUPPORT_OutputType_APA102 // SPI
#define SUPPORT_OutputType_DMX // UART
#define SUPPORT_OutputType_GECE // UART
#define SUPPORT_OutputType_GS8208 // UART / RMT
#define SUPPORT_OutputType_Renard // UART
#define SUPPORT_OutputType_Serial // UART
#define SUPPORT_OutputType_TM1814 // UART / RMT
#define SUPPORT_OutputType_UCS1903 // UART / RMT
#define SUPPORT_OutputType_UCS8903 // UART / RMT
// #define SUPPORT_OutputType_WS2801 // SPI
#define SUPPORT_OutputType_WS2811 // UART / RMT
#define SUPPORT_OutputType_Relay // GPIO
// #define SUPPORT_OutputType_Servo_PCA9685 // I2C (default pins)
58 changes: 35 additions & 23 deletions dist/firmware/firmware.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,29 +71,6 @@
"offset": "0x200000"
}
},
{
"name": "D1 Mini PRO 16MB Flash",
"description": "Generic D1 Mini PRO 16MB Flash for DIY builds",
"chip": "esp8266",
"appbin": "esp8266/d1_mini_pro-app.bin",
"esptool": {
"baudrate": "921600",
"options": "--before default_reset --after hard_reset",
"flashcmd": "write_flash"
},
"binfiles": [
{
"name": "esp8266/d1_mini_pro-app.bin",
"offset": "0x0"
}
],
"filesystem": {
"page": "256",
"block": "8192",
"size": "4145152",
"offset": "0x400000"
}
},
{
"name": "D1 Mini Mhetesp32minikit",
"description": "D1 Mini Mhetesp32minikit module with PSRAM support for DIY builds",
Expand Down Expand Up @@ -339,6 +316,41 @@
"offset": "0x3B0000"
}
},
{
"name": "ESP32 BONG 69",
"description": "ESP32 8 port eth controller",
"chip": "esp32",
"appbin": "esp32/esp32_bong69-app.bin",
"esptool": {
"baudrate": "460800",
"options": "--before default_reset --after hard_reset",
"flashcmd": "write_flash -z"
},
"binfiles": [
{
"name": "esp32/esp32_bong69-bootloader.bin",
"offset": "0x1000"
},
{
"name": "esp32/esp32_bong69-partitions.bin",
"offset": "0x8000"
},
{
"name": "esp32/boot_app0.bin",
"offset": "0xe000"
},
{
"name": "esp32/esp32_bong69-app.bin",
"offset": "0x10000"
}
],
"filesystem": {
"page": "256",
"block": "4096",
"size": "0x50000",
"offset": "0x3B0000"
}
},
{
"name": "ESP32 WTEth 01",
"description": "ESP32 for DIY builds",
Expand Down
2 changes: 1 addition & 1 deletion dist/fs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
"sta_timeout": 15,
"ap_fallback": false,
"ap_timeout": 120,
"ap_reboot": true
"ap_reboot": false
}
}
Loading