From f7cf84ecff5c6d82320e34f10c08f38a4e77f55d Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Sat, 20 Nov 2021 10:53:17 -0500 Subject: [PATCH] Fixed issue in the ISR that caused a misalignment in processing Changed order of processing to process threshold events before frame done events Added stats collection to help debug ISR issues. Reporting is disabled. --- ESPixelStick/src/output/OutputRmt.cpp | 82 +++++++++++++++++---- ESPixelStick/src/output/OutputRmt.hpp | 10 ++- ESPixelStick/src/output/OutputWS2811Rmt.cpp | 7 ++ ESPixelStick/src/output/OutputWS2811Rmt.hpp | 1 + 4 files changed, 81 insertions(+), 19 deletions(-) diff --git a/ESPixelStick/src/output/OutputRmt.cpp b/ESPixelStick/src/output/OutputRmt.cpp index e5f5c1c64..67a5da1c3 100644 --- a/ESPixelStick/src/output/OutputRmt.cpp +++ b/ESPixelStick/src/output/OutputRmt.cpp @@ -134,35 +134,68 @@ void c_OutputRmt::Begin (rmt_channel_t ChannelId, //---------------------------------------------------------------------------- void IRAM_ATTR c_OutputRmt::ISR_Handler () { - if (RMT.int_st.val & RMT_INT_TX_END_BIT) - { - RMT.int_clr.val = RMT_INT_TX_END_BIT; - RMT.int_clr.val = RMT_INT_THR_EVNT_BIT; - - RMT.int_ena.val &= ~RMT_INT_TX_END_BIT; - RMT.int_ena.val &= ~RMT_INT_THR_EVNT_BIT; + register uint32_t int_st = RMT.int_st.val; - // ISR_Handler_StartNewFrame (); - } - else if (RMT.int_st.val & RMT_INT_THR_EVNT_BIT) + do // once { - // RMT.int_ena.val &= ~RMT_INT_THR_EVNT (RmtChannelId); - RMT.int_clr.val = RMT_INT_THR_EVNT_BIT; + if (!(int_st & (RMT_INT_TX_END_BIT | RMT_INT_RX_END | RMT_INT_ERROR | RMT_INT_THR_EVNT))) + { + IsrIsNotForUs++; + break; + } - if (OutputPixel->MoreDataToSend ()) + if (RMT.int_st.val & RMT_INT_THR_EVNT_BIT) { - ISR_Handler_SendIntensityData (); + DataISRcounter++; + + // RMT.int_ena.val &= ~RMT_INT_THR_EVNT (RmtChannelId); + RMT.int_clr.val = RMT_INT_THR_EVNT_BIT; + + if (OutputPixel->MoreDataToSend ()) + { + ISR_Handler_SendIntensityData (); + } + else + { + RMT.int_ena.val &= ~RMT_INT_THR_EVNT_BIT; + } + break; } - else + + if (int_st & RMT_INT_TX_END_BIT) { + FrameEndISRcounter++; + + RMT.int_clr.val = RMT_INT_TX_END_BIT; + RMT.int_clr.val = RMT_INT_THR_EVNT_BIT; + + RMT.int_ena.val &= ~RMT_INT_TX_END_BIT; RMT.int_ena.val &= ~RMT_INT_THR_EVNT_BIT; + + // ISR_Handler_StartNewFrame (); + break; } - } + + if (int_st & RMT_INT_ERROR_BIT) + { + ErrorIsr++; + } + + if (int_st & RMT_INT_RX_END_BIT) + { + RxIsr++; + } + + } while (false); + + } // ISR_Handler //---------------------------------------------------------------------------- void IRAM_ATTR c_OutputRmt::ISR_Handler_StartNewFrame () { + FrameStartCounter++; + RMT.conf_ch[RmtChannelId].conf1.mem_rd_rst = 1; // set the internal pointer to the start of the mem block RMT.conf_ch[RmtChannelId].conf1.mem_rd_rst = 0; @@ -249,4 +282,21 @@ bool c_OutputRmt::Render () } // render +//---------------------------------------------------------------------------- +void c_OutputRmt::GetStatus (ArduinoJson::JsonObject& jsonStatus) +{ + jsonStatus[" DataISRcounter: "] = DataISRcounter; + jsonStatus["FrameEndISRcounter: "] = FrameEndISRcounter; + jsonStatus[" FrameStartCounter: "] = FrameStartCounter; + jsonStatus[" ErrorIsr: "] = ErrorIsr; + jsonStatus[" RxIsr: "] = RxIsr; + jsonStatus[" IsrIsNotForUs: "] = IsrIsNotForUs; + + jsonStatus[" Raw int_ena: 0x"] = String (RMT.int_ena.val, HEX); + jsonStatus[" int_ena: 0x"] = String (RMT.int_ena.val & (RMT_INT_TX_END_BIT | RMT_INT_THR_EVNT_BIT), HEX); + jsonStatus[" int_st: 0x"] = String (RMT.int_st.val & (RMT_INT_TX_END_BIT | RMT_INT_THR_EVNT_BIT), HEX); + jsonStatus[" Raw int_st: 0x"] = String (RMT.int_st.val, HEX); + +} // GetStatus + #endif // def ARDUINO_ARCH_ESP32 diff --git a/ESPixelStick/src/output/OutputRmt.hpp b/ESPixelStick/src/output/OutputRmt.hpp index b0cda6513..1f5076242 100644 --- a/ESPixelStick/src/output/OutputRmt.hpp +++ b/ESPixelStick/src/output/OutputRmt.hpp @@ -58,9 +58,12 @@ class c_OutputRmt uint8_t NumIntensityBitsPerInterrupt = 0; // debug counters - // uint32_t DataISRcounter = 0; - // uint32_t FrameEndISRcounter = 0; - // uint32_t FrameStartCounter = 0; + uint32_t DataISRcounter = 0; + uint32_t FrameEndISRcounter = 0; + uint32_t FrameStartCounter = 0; + uint32_t RxIsr = 0; + uint32_t ErrorIsr = 0; + uint32_t IsrIsNotForUs = 0; public: c_OutputRmt (); @@ -68,6 +71,7 @@ class c_OutputRmt void Begin (rmt_channel_t ChannelId, gpio_num_t DataPin, c_OutputPixel * OutputPixel, rmt_idle_level_t idle_level); bool Render (); + void GetStatus (ArduinoJson::JsonObject& jsonStatus); void set_pin (gpio_num_t _DataPin) { DataPin = _DataPin; rmt_set_gpio (RmtChannelId, rmt_mode_t::RMT_MODE_TX, DataPin, false); } void SetNumIdleBits (uint8_t Value) { NumIdleBits = Value; } diff --git a/ESPixelStick/src/output/OutputWS2811Rmt.cpp b/ESPixelStick/src/output/OutputWS2811Rmt.cpp index 3547b7268..f71fb0b8b 100644 --- a/ESPixelStick/src/output/OutputWS2811Rmt.cpp +++ b/ESPixelStick/src/output/OutputWS2811Rmt.cpp @@ -127,6 +127,13 @@ bool c_OutputWS2811Rmt::SetConfig (ArduinoJson::JsonObject& jsonConfig) } // SetConfig +//---------------------------------------------------------------------------- +void c_OutputWS2811Rmt::GetStatus (ArduinoJson::JsonObject& jsonStatus) +{ + c_OutputWS2811::GetStatus (jsonStatus); + // Rmt.GetStatus (jsonStatus); +} // GetStatus + //---------------------------------------------------------------------------- void c_OutputWS2811Rmt::Render () { diff --git a/ESPixelStick/src/output/OutputWS2811Rmt.hpp b/ESPixelStick/src/output/OutputWS2811Rmt.hpp index 8ea922056..87e9523b2 100644 --- a/ESPixelStick/src/output/OutputWS2811Rmt.hpp +++ b/ESPixelStick/src/output/OutputWS2811Rmt.hpp @@ -40,6 +40,7 @@ class c_OutputWS2811Rmt : public c_OutputWS2811 void Begin (); ///< set up the operating environment based on the current config (or defaults) bool SetConfig (ArduinoJson::JsonObject& jsonConfig); ///< Set a new config in the driver void Render (); ///< Call from loop (), renders output data + void GetStatus (ArduinoJson::JsonObject& jsonStatus); private: