From 3bd63bffce896be09644b8f6e97c44448cc12ea5 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Sun, 25 Aug 2024 20:19:51 -0700 Subject: [PATCH] Esp32 bit bang pins above 31 are supported (#829) must be output pins. caveat, there seems to be a GCC bug cause the compiler to incorrectly produce code around one of the changes, due to union with a 32bit and 8:24 bit. The IO registers must be written as 32 bits but the compiler keeps short circuit the code even though it is written to write the whole 32 bits. The official pinMode() code has a work around in it for this but that doesn't fit into the bitbang code. This issue maybe already fixed with newer IDF with a newer GCC as this has been reported to work from others. --- src/internal/methods/NeoEspBitBangMethod.cpp | 39 +++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/internal/methods/NeoEspBitBangMethod.cpp b/src/internal/methods/NeoEspBitBangMethod.cpp index 4665f71..a7304dd 100644 --- a/src/internal/methods/NeoEspBitBangMethod.cpp +++ b/src/internal/methods/NeoEspBitBangMethod.cpp @@ -101,8 +101,8 @@ bool IRAM_ATTR neoEspBitBangWriteSpacingPixels(const uint8_t* pixels, uint32_t tLatch, bool invert) { - uint32_t setValue = _BV(pin); - uint32_t clearValue = _BV(pin); + uint32_t setValue = _BV(pin % 32); + uint32_t clearValue = _BV(pin % 32); uint8_t mask = 0x80; uint8_t subpix = *pixels++; uint8_t element = 0; @@ -110,16 +110,35 @@ bool IRAM_ATTR neoEspBitBangWriteSpacingPixels(const uint8_t* pixels, uint32_t cyclesNext = 0; #if defined(ARDUINO_ARCH_ESP32) + + volatile uint32_t* setRegister; + volatile uint32_t* clearRegister; + #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) - volatile uint32_t* setRegister = &GPIO.out_w1ts.val; - volatile uint32_t* clearRegister = &GPIO.out_w1tc.val; - setValue = _BV(pin); - clearValue = _BV(pin); -#else - volatile uint32_t* setRegister = &GPIO.out_w1ts; - volatile uint32_t* clearRegister = &GPIO.out_w1tc; + if (pin < 32) + { + setRegister = &GPIO.out_w1ts.val; + clearRegister = &GPIO.out_w1tc.val; + } + else + { + setRegister = &GPIO.out1_w1ts.val; + clearRegister = &GPIO.out1_w1tc.val; + } +#else // just ESP32, ESP32S2 + if (pin < 32) + { + setRegister = &GPIO.out_w1ts; + clearRegister = &GPIO.out_w1tc; + } + else + { + setRegister = &GPIO.out1_w1ts.val; + clearRegister = &GPIO.out1_w1tc.val; + } #endif // defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) -#else + +#else // just ESP8266 uint32_t setRegister = PERIPHS_GPIO_BASEADDR + GPIO_OUT_W1TS_ADDRESS; uint32_t clearRegister = PERIPHS_GPIO_BASEADDR + GPIO_OUT_W1TC_ADDRESS; if (pin == 16)