Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
86addea
Removed redundant advancedMode definitions.
MartinMueller2003 Jul 24, 2026
8881ae1
Fixed issue that removed the ability to modify the output GPIO values
MartinMueller2003 Jul 24, 2026
bf7ed33
Updated to most recent settings.
MartinMueller2003 Jul 24, 2026
406a368
Merge branch 'forkineye:main' into main
MartinMueller2003 Jul 24, 2026
e412871
Checkpoint
MartinMueller2003 Aug 11, 2026
1c41650
Remove idftest from default build
MartinMueller2003 Aug 11, 2026
ad89cce
Added conditional I2S support.
MartinMueller2003 Aug 11, 2026
9f0cf32
changed compile trigger
MartinMueller2003 Aug 11, 2026
b840f72
Fixed feature exclusion setting
MartinMueller2003 Aug 11, 2026
00c3973
fixed feature exclusion setting
MartinMueller2003 Aug 11, 2026
4e583a2
Fine grained support for output HW type.
MartinMueller2003 Aug 18, 2026
5124ded
Made new settings pretty
MartinMueller2003 Aug 18, 2026
cc197a7
Added fine grained HW support.
MartinMueller2003 Aug 18, 2026
c85be0f
Renamed startNewFrame method.
MartinMueller2003 Aug 28, 2026
2c000bf
Added debug macro.
MartinMueller2003 Aug 28, 2026
858121b
Code format change
MartinMueller2003 Aug 28, 2026
2cbd42e
Renamed new frame and made the new frame calls ISR compatible.
MartinMueller2003 Aug 28, 2026
435e607
Added debug counter macro
MartinMueller2003 Aug 28, 2026
68ad37b
Removed old file.
MartinMueller2003 Aug 28, 2026
68d1695
Rename new frame method
MartinMueller2003 Aug 28, 2026
7ad98b9
Lots of cleanup.
MartinMueller2003 Sep 1, 2026
79c5611
Lots of cleanup.
MartinMueller2003 Sep 1, 2026
6d3751a
Preparing for I2S. Have to move some functionality back into IRAM
MartinMueller2003 Sep 1, 2026
20f41d7
Moving UART bits into IRAM
MartinMueller2003 Sep 1, 2026
12cb479
Moving methods to IRAM
MartinMueller2003 Sep 1, 2026
9da1239
Dont load I2S driver.
MartinMueller2003 Sep 1, 2026
93a181e
Remove unneeded IRAM_ATTR flag.
MartinMueller2003 Sep 4, 2026
ada0132
Rename functions
MartinMueller2003 Sep 4, 2026
0118a54
Removed FrameStartTimeInMicroSec from the I2S builds.
MartinMueller2003 Sep 4, 2026
aee040e
Formatting changes
MartinMueller2003 Sep 4, 2026
01d8534
Functional name changes
MartinMueller2003 Sep 4, 2026
1679242
Fixed compiler warning
MartinMueller2003 Sep 4, 2026
7014a01
Refactored function name.
MartinMueller2003 Sep 4, 2026
9b1c6b5
Fixed functions called in the ISR.
MartinMueller2003 Sep 4, 2026
9fedabe
Fixed issue that failed to rename the unziped file from xLights
MartinMueller2003 Sep 11, 2026
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
4 changes: 2 additions & 2 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"Jason2866.esp-decoder",
"pioarduino.pioarduino-ide",
"platformio.platformio-ide"
],
"unwantedRecommendations": [
Expand Down
5 changes: 3 additions & 2 deletions boards/seeed_xiao_esp32s3-custom.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"core": "esp32",
"extra_flags": [
"-DARDUINO_ESP32S3_DEV",
"-DARDUINO_XIAO_ESP32S3",
"-DARDUINO_USB_MODE=1",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_RUNNING_CORE=1",
Expand All @@ -27,7 +28,7 @@
]
],
"mcu": "esp32s3",
"variant": "esp32s3"
"variant": "XIAO_ESP32S3"
},
"connectivity": [
"wifi"
Expand All @@ -53,4 +54,4 @@
},
"url": "https://www.seeedstudio.com/XIAO-ESP32S3-p-5627.html",
"vendor": "Seeed Studio"
}
}
4 changes: 2 additions & 2 deletions html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@

<!-- Advanced Mode -->
<div class="hidden AdvancedMode">
<div class="form-group hidden AdvancedMode">
<div class="form-group">
<label class="control-label col-sm-2 esp32" for="sdspeed">SD Speed (MHz)</label>
<div class="col-sm-2 esp32">
<input type="number" class="form-control is-valid esp32" id="sdspeed" step="1"
Expand All @@ -694,7 +694,7 @@
</div>
</div>

<div class="form-group hidden AdvancedMode">
<div class="form-group">
<label class="control-label col-sm-2" for="miso_pin">SD MISO Pin</label>
<div class="col-sm-4">
<input type="number" class="form-control is-valid" id="miso_pin" step="1" min="0"
Expand Down
45 changes: 39 additions & 6 deletions html/js/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ var System_Config = null;
var Fseq_File_List = [];
var selector = [];
var ajaxQueue = $({}); // Create an empty jQuery object to act as a queue
/**
* @type {string[]}
*/
var ListOfLoadedOutputElements = [];

var SdCardIsInstalled = false;
var FseqFileTransferStartTime = new Date();
Expand Down Expand Up @@ -621,14 +625,38 @@ function UpdateAdvancedOptionsMode(){
let am = $('#AdvancedOptions');
let AdvancedModeState = am.prop("checked");

$(".AdvancedMode").each(function () {
if (true === AdvancedModeState) {
$(this).removeClass("hidden");
const collection = document.getElementsByClassName('AdvancedMode');
$(collection).each(function (p, element)
{
// console.debug("Processing element: ", element);
if (true === AdvancedModeState)
{
$(element).removeClass("hidden");
}
else {
$(this).addClass("hidden");
else
{
$(element).addClass("hidden");
}
});

$(ListOfLoadedOutputElements).each(function (p, element)
{
// console.debug("Processing loaded output element: ", element);
const subElements = $(element).find('.AdvancedMode');
$(subElements).each(function (p, element)
{
// console.debug("Processing loaded output element: ", element);
if (true === AdvancedModeState)
{
$(element).removeClass("hidden");
}
else
{
$(element).addClass("hidden");
}
});
});

} // UpdateAdvancedOptionsMode

function UpdateChannelCounts() {
Expand Down Expand Up @@ -1448,7 +1476,9 @@ function ProcessConfigElements(StartingElementId, channelConfig)
// console.debug("LoadLocation: " + LoadLocation);
$(LoadLocation).load(LoadName, function()
{
ListOfLoadedOutputElements.push(LoadLocation);
ProcessConfigElements(LoadLocation, channelConfig);
UpdateAdvancedOptionsMode();
});
return $(this).attr('id');
}).get();
Expand Down Expand Up @@ -1513,7 +1543,10 @@ function ProcessModeConfigurationData(channelId, ChannelType, JsonConfig) {
// console.debug("ModeDisplayName: " + ModeDisplayName);
$(modeControlName + ' #Title')[0].innerHTML = ModeDisplayName;
}

if("output" === ChannelType)
{
ListOfLoadedOutputElements = [];
}
ProcessConfigElements(modeControlName, channelConfig);

// by default, do not show the ECB config data
Expand Down
17 changes: 9 additions & 8 deletions include/output/OutputCommon.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ class c_OutputCommon
virtual bool RmtPoll () = 0; ///< Call from loop(), renders output data
#endif // def ARDUINO_ARCH_ESP32
virtual void GetDriverName (String & sDriverName) = 0; ///< get the name for the instantiated driver
OM_PortId_t GetOutputPortId () { return OutputPortDefinition.PortId; } ///< return the output channel number
uint8_t * GetBufferAddress () { return pOutputBuffer;} ///< Get the address of the buffer into which the E1.31 handler will stuff data
uint32_t GetBufferUsedSize () { return OutputBufferSize;} ///< Get the address of the buffer into which the E1.31 handler will stuff data
OM_GPIOS_t GetOutputGpio () { return OutputPortDefinition.gpios; }
OTYPE_t GetOutputType () { return OutputType; } ///< Have the instance report its type.
inline OM_PortId_t GetOutputPortId () { return OutputPortDefinition.PortId; } ///< return the output channel number
inline uint8_t * ISR_GetBufferAddress(){ return pOutputBuffer;} ///< Get the address of the buffer into which the E1.31 handler will stuff data
inline uint32_t GetBufferUsedSize () { return OutputBufferSize;} ///< Get the address of the buffer into which the E1.31 handler will stuff data
inline OM_GPIOS_t GetOutputGpio () { return OutputPortDefinition.gpios; }
inline OTYPE_t GetOutputType () { return OutputType; } ///< Have the instance report its type.
virtual void GetStatus (ArduinoJson::JsonObject & jsonStatus) = 0;
virtual void BaseGetStatus (ArduinoJson::JsonObject & jsonStatus);
void SetOutputBufferAddress (uint8_t* pNewOutputBuffer) { pOutputBuffer = pNewOutputBuffer; }
Expand All @@ -62,7 +62,7 @@ class c_OutputCommon
virtual void ReadChannelData (uint32_t StartChannelId, uint32_t ChannelCount, byte *pTargetData);
virtual bool ValidateGpio (gpio_num_t ConsoleTxGpio, gpio_num_t ConsoleRxGpio);
virtual uint32_t GetFrameTimeMs() {return 1 + (ActualFrameDurationMicroSec / 1000); }
bool IsPaused() {return Paused;}
inline bool IsPaused() {return Paused;}
virtual void ClearStatistics (void);

protected:
Expand All @@ -77,8 +77,8 @@ class c_OutputCommon
uint32_t FrameCount = 0;
bool Paused = false;

virtual void ReportNewFrame ();

void ISR_ReportNewFrame ();
#ifndef SUPPORT_I2S
inline bool canRefresh ()
{
uint32_t Now = micros ();
Expand All @@ -95,4 +95,5 @@ class c_OutputCommon

private: uint32_t FrameStartTimeInMicroSec = 0;
public: uint32_t GetFrameStartTimeInMicroSec() {return FrameStartTimeInMicroSec;}
#endif // ndef SUPPORT_I2S
}; // c_OutputCommon
6 changes: 3 additions & 3 deletions include/output/OutputGECERmt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*
*/
#include "ESPixelStick.h"
#if defined(SUPPORT_OutputProtocol_GECE) && defined(ARDUINO_ARCH_ESP32)
#if defined(SUPPORT_OutputProtocol_GECE) && defined(SUPPORT_RMT)

#include "OutputGECE.hpp"
#include "OutputRmt.hpp"
Expand All @@ -45,7 +45,7 @@ class c_OutputGECERmt : public c_OutputGECE
void GetStatus (ArduinoJson::JsonObject& jsonStatus);
void SetOutputBufferSize (uint32_t NumChannelsAvailable);
void PauseOutput (bool State);
void StartNewDataFrame();
void ISR_StartNewDataFrame();
bool ISR_GetNextBitToSend (rmt_item32_t & DataToSend);

private:
Expand Down Expand Up @@ -90,4 +90,4 @@ class c_OutputGECERmt : public c_OutputGECE

}; // c_OutputGECERmt

#endif // defined(SUPPORT_OutputProtocol_GECE) && defined(ARDUINO_ARCH_ESP32)
#endif // defined(SUPPORT_OutputProtocol_GECE) && defined(SUPPORT_RMT)
7 changes: 2 additions & 5 deletions include/output/OutputGECEUart.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/

#include "ESPixelStick.h"
#if defined(SUPPORT_OutputProtocol_GECE)
#if defined(SUPPORT_OutputProtocol_GECE) && defined(SUPPORT_UART)

#include "OutputGECE.hpp"
#include "OutputUart.hpp"
Expand All @@ -39,9 +39,6 @@ class c_OutputGECEUart : public c_OutputGECE
// functions to be provided by the derived class
void Begin (); ///< set up the operating environment based on the current config (or defaults)
uint32_t Poll (); ///< Call from loop(), renders output data
#if defined(ARDUINO_ARCH_ESP32)
bool RmtPoll () {return false;}
#endif // defined(ARDUINO_ARCH_ESP32)
void PauseOutput (bool State);
bool SetConfig (ArduinoJson::JsonObject& jsonConfig);
void GetConfig (ArduinoJson::JsonObject& jsonConfig);
Expand All @@ -65,4 +62,4 @@ class c_OutputGECEUart : public c_OutputGECE

}; // c_OutputGECEUart

#endif // defined(SUPPORT_OutputProtocol_GECE)
#endif // defined(SUPPORT_OutputProtocol_GECE) && defined(SUPPORT_UART)
6 changes: 3 additions & 3 deletions include/output/OutputGS8208Rmt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/
#include "ESPixelStick.h"

#if defined(SUPPORT_OutputProtocol_GS8208) && defined(ARDUINO_ARCH_ESP32)
#if defined(SUPPORT_OutputProtocol_GS8208) && defined(SUPPORT_RMT)

#include "OutputGS8208.hpp"
#include "OutputRmt.hpp"
Expand All @@ -44,7 +44,7 @@ class c_OutputGS8208Rmt : public c_OutputGS8208
void GetStatus (ArduinoJson::JsonObject& jsonStatus);
void SetOutputBufferSize (uint32_t NumChannelsAvailable);
void PauseOutput (bool State);
void StartNewDataFrame();
void ISR_StartNewDataFrame();
bool ISR_GetNextBitToSend (rmt_item32_t & DataToSend);

private:
Expand Down Expand Up @@ -87,4 +87,4 @@ class c_OutputGS8208Rmt : public c_OutputGS8208

}; // c_OutputGS8208Rmt

#endif // defined(SUPPORT_OutputProtocol_GS8208) && defined(ARDUINO_ARCH_ESP32)
#endif // defined(SUPPORT_OutputProtocol_GS8208) && defined(SUPPORT_RMT)
7 changes: 2 additions & 5 deletions include/output/OutputGS8208Uart.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

#include "OutputCommon.hpp"

#if defined(SUPPORT_OutputProtocol_GS8208)
#if defined(SUPPORT_OutputProtocol_GS8208) && defined(SUPPORT_UART)

#include "OutputGS8208.hpp"
#include "OutputUart.hpp"
Expand All @@ -40,9 +40,6 @@ class c_OutputGS8208Uart : public c_OutputGS8208
// functions to be provided by the derived class
void Begin (); ///< set up the operating environment based on the current config (or defaults)
uint32_t Poll (); ///< Call from loop(), renders output data
#if defined(ARDUINO_ARCH_ESP32)
bool RmtPoll () {return false;}
#endif // defined(ARDUINO_ARCH_ESP32)
void PauseOutput (bool State);
bool SetConfig (ArduinoJson::JsonObject& jsonConfig);
void GetConfig (ArduinoJson::JsonObject& jsonConfig);
Expand All @@ -55,4 +52,4 @@ class c_OutputGS8208Uart : public c_OutputGS8208

}; // c_OutputGS8208Uart

#endif // defined(SUPPORT_OutputProtocol_GS8208)
#endif // defined(SUPPORT_OutputProtocol_GS8208) && defined(SUPPORT_UART)
111 changes: 111 additions & 0 deletions include/output/OutputI2S.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#pragma once
/*
* OutputI2S.hpp - I2S driver code for ESPixelStick I2S Channel
*
* Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver
* Copyright (c) 2026 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.
*
*/

#ifdef SUPPORT_I2S
#include "ESPixelStick.h"
#include "i2s_parallel.hpp"
#include "driver/gpio.h"

// #define USE_I2S_DEBUG_COUNTERS

class c_OutputI2S
{
public:
// a slot is one bit in the output item
#define I2S_NUM_SLOTA i2s_bits_per_chan_t::I2S_BITS_PER_CHAN_8BIT
#define I2S_MAX_NUM_PORTS 8
typedef uint8_t I2S_Item_t;

struct OutputI2SChannelConfig_t
{
uint32_t I2SChannelId;
gpio_num_t DataPin;
void *arg;
void (*GetNextIntensityBitSlices) (void*arg, I2S_Item_t * data, uint32_t numSlices) = nullptr;
bool IsActive;
};

// must be a multiple of 32
#define I2S_NumSendBufferItems 1024

struct TransmitDmaBuffer_t
{
alignas (4) lldesc_t header; // must be first
#ifdef USE_I2S_DEBUG_COUNTERS
alignas (4) uint32_t id;
alignas (4) uint32_t UsageCounter;
#endif // def USE_I2S_DEBUG_COUNTERS
alignas (4) I2S_Item_t data[I2S_NumSendBufferItems];
};

private:
// array of configuration settings
OutputI2SChannelConfig_t OutputI2SSlotConfigs[I2S_MAX_NUM_PORTS];

// must be more than zero
#define I2S_NumSendBuffers 4

// Class to manage the io device
esp_i2s_parallel i2sParallel;

public:
c_OutputI2S ();
virtual ~c_OutputI2S ();

void Begin ();
void RegisterSlotDevice (OutputI2SChannelConfig_t config, uint32_t * DataBit, uint32_t * DataBitMask);
void RemoveSlotDevice (uint32_t I2SChannelId);
void GetStatus (ArduinoJson::JsonObject& jsonStatus);
void GetDriverName (String &value) { value = F("I2S"); }
uint32_t GetNumTimeSlicesForTargetTimeNS (uint32_t BitTimeInNanoSec);
void SetOutputState (uint32_t I2SChannelId, bool NewState);
void SetGpio (uint32_t I2SChannelId, gpio_num_t NewGpio);
void ISR_Handler (void * _TransmitDmaBuffer);

#ifdef USE_I2S_DEBUG_COUNTERS
// debug counters
struct I2SDebugCounters_t
{
uint32_t DataTaskcounter = 0;
uint32_t IntensityBitsSent = 0;
uint32_t IntensityBitsSentLastFrame = 0;
uint32_t I2SEntriesTransfered = 0;
uint32_t I2SXmtFills = 0;
uint32_t ISRpaused = 0;
uint32_t WriteToBuffer = 0;
uint32_t ISR_handler_count = 0;
uint32_t ISR_FillBuffer = 0;
uint32_t BufferOwnerFlagError = 0;
uint32_t ISR_NullBufferPointer = 0;
};
I2SDebugCounters_t I2SDebugCounters;

#define I2S_DEBUG_INC_COUNTER(p) (++I2SDebugCounters.p)
#define I2S_DEBUG_COUNTER(p) (I2SDebugCounters.p)

#else

#define I2S_DEBUG_INC_COUNTER(p)
#define I2S_DEBUG_COUNTER(p)

#endif // def USE_I2S_DEBUG_COUNTERS

};
#endif // def #ifdef SUPPORT_I2S
Loading
Loading